zoukankan      html  css  js  c++  java
  • 代理模式

    代理模式:为其他对象提供一种代理,以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介的作用。

    假设一个场景:明星需要出演活动(比如唱歌),那么他需要签合同,收款等工作。但是对于明星来讲,这都是琐碎的事情,而且亲自来做,比较掉价,所以明星们一般都会设置一个代理(也就是经纪人),经纪人负责签合同,收款等这些琐碎的工作,明星本人只需要专注于唱歌这一件事情就可以了。

    使用代理模式的好处:

    • 被代理类可以更加专注于主要功能的实现
    • 代理类可以在被代理类已经存在的功能上添加新的功能

    我们用代码来模拟这个过程。

    静态代理:

    写一个Star接口

     1 package top.bigking.proxy.staticProxy;
     2 
     3 /**
     4  * @Author ABKing
     5  * @Date 2020/2/14 下午9:33
     6  **/
     7 public interface Star {
     8     /**
     9      * 签合同
    10      */
    11     public void signContract();
    12     /**
    13      * 唱歌
    14      */
    15     public void sing();
    16     /**
    17      * 收尾款
    18      */
    19     public void collectMoney();
    20 }

    让明星RealStar类实现这个接口:

     1 package top.bigking.proxy.staticProxy;
     2 
     3 /**
     4  * @Author ABKing
     5  * @Date 2020/2/14 下午10:01
     6  **/
     7 public class RealStar implements Star {
     8     @Override
     9     public void signContract() {
    10         System.out.println("ReadStar.signContract");
    11     }
    12 
    13     @Override
    14     public void sing() {
    15         System.out.println("蔡徐坤本人唱歌");
    16     }
    17 
    18     @Override
    19     public void collectMoney() {
    20         System.out.println("ReadStar.collectMoney");
    21     }
    22 }

    让代理ProxyStar类实现这个接口:

     1 package top.bigking.proxy.staticProxy;
     2 
     3 /**
     4  * @Author ABKing
     5  * @Date 2020/2/14 下午10:02
     6  **/
     7 public class ProxyStar implements Star {
     8     private Star star;
     9 
    10     public ProxyStar(Star star) {
    11         this.star = star;
    12     }
    13 
    14     @Override
    15     public void signContract() {
    16         System.out.println("ProxyStar.signContract");
    17     }
    18 
    19     @Override
    20     public void sing() {
    21         star.sing();
    22     }
    23 
    24     @Override
    25     public void collectMoney() {
    26         System.out.println("ProxyStar.collectMoney");
    27     }
    28 }

    进行JUnit测试:

     1 package top.bigking.proxy.staticProxy;
     2 
     3 import org.junit.Test;
     4 
     5 /**
     6  * @Author ABKing
     7  * @Date 2020/2/14 下午10:04
     8  **/
     9 public class TestStaticProxy {
    10     @Test
    11     public void testStaticProxy(){
    12         Star realStar = new RealStar();
    13         Star proxyStar = new ProxyStar(realStar);
    14         proxyStar.signContract();
    15         proxyStar.sing();
    16         proxyStar.collectMoney();
    17     }
    18 }

    结果如下:

    ProxyStar.signContract
    蔡徐坤本人唱歌
    ProxyStar.collectMoney
    

     

    动态代理:

    JDK动态代理:

    Star接口和RealStar类不变

    写一个StarHandler类:

     1 package top.bigking.proxy.dynamicProxy;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 
     6 /**
     7  * @Author ABKing
     8  * @Date 2020/2/14 下午11:16
     9  **/
    10 public class StarHandler implements InvocationHandler {
    11     private Star star;
    12 
    13     public StarHandler(Star star) {
    14         this.star = star;
    15     }
    16 
    17     @Override
    18     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    19         if(method.getName().equals("sing")) {
    20             method.invoke(star, args);
    21         }
    22         System.out.println(method.getName());
    23         return null;
    24     }
    25 }

    执行JUnit单元测试:

     1 package top.bigking.proxy.dynamicProxy;
     2 
     3 import org.junit.Test;
     4 
     5 import java.lang.reflect.Proxy;
     6 
     7 /**
     8  * @Author ABKing
     9  * @Date 2020/2/14 下午11:22
    10  **/
    11 public class TestDynamicProxy {
    12     @Test
    13     public void testDynamicProxy(){
    14         Star realStar = new RealStar();
    15         StarHandler starHandler = new StarHandler(realStar);
    16         Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
    17                 new Class[]{Star.class}, starHandler);
    18         proxy.signContract();
    19         proxy.sing();
    20         proxy.collectMoney();
    21     }
    22 }

    运行结果如下:

    signContract
    蔡徐坤本人唱歌sing
    collectMoney

    开发框架中应用场景:

    • Struts2中拦截器的实现
    • 数据库连接池关闭处理
    • Hibernate中延时加载的实现
    • mybatis中实现拦截器插件
    • AspectJ的实现
    • spring中AOP的实现:日志拦截,声明式事务处理
    • web service
    • RMI远程方法调用
    金麟岂是池中物,一遇风云便化龙!
  • 相关阅读:
    常用字段类型
    触发事件中的sender
    $符号基本用法$() ${} $(())
    expect语法
    apt 和 apt-get的区别
    python字符串中 r'', b'', u'', f'' 的含义
    linux正则表达式
    Linux下apt-get命令详解(安装、卸载、更新、查询软件包)
    创建linux service服务
    Ubuntu下deb包的解包、打包
  • 原文地址:https://www.cnblogs.com/ABKing/p/12309931.html
Copyright © 2011-2022 走看看