JAVA设计模式之代理模式(Proxy)

代理模式

  • 一、代理模式作用
    业务逻辑上线使用后,如果还有一些另外的与原本逻辑无关的需求,并且尽量不要改动原本的调用方式,可以采用代理模式来进行原本业务功能的增强。
  • 二、代理模式实现要素
    • 1、要有代理类和被代理类
    • 2、代理类和被代理类实现相同的接口
    • 3、代理类要依赖被代理类,因为需要被代理类来实现业务逻辑
  • 三、静态代理
    下面,我们就用代码的方式来展现静态代理模式的使用方式:
    • 代码
      /**
       * 简单接口
       */
      public interface Hello {
          public void sayHello();
      }
      
      /**
       * 简单接口的实现类
       */
      class HelloImpl implements Hello {
      
          @Override
          public void sayHello() {
              System.out.println("hello, world");
          }
      }
      
      /**
       * 代理类,类中注入被代理对象,并进行功能的增强
       */
      class HelloImplProxy implements Hello {
          //被代理对象
          private Hello target ;
          
          //通过构造器注入被代理对象
          public HelloImplProxy(Hello target){
              this.target = target;
          }
          
          //在相同方法中调用被代理对象,并且实现功能的增强
          @Override
          public void sayHello() {
              System.out.println("sayHello method start");
              target.sayHello();
              System.out.println("sayHello method end");
          }
      }
      
    • 测试
      public static void main(String[] args) {
          Hello hello = new HelloImpl();
          hello.sayHello();
          
      	System.out.println("=================below is proxy mode====================");
      
          Hello helloProxy = new HelloImplProxy(hello);
          helloProxy.sayHello();
      }
      
    • 结果
      hello, world
      =================below is proxy mode====================
      sayHello method start
      hello, world
      sayHello method end
      
      从上面的结果可以看出,被代理对象实现了基础的业务逻辑,代理对象保留了原本业务逻辑的调用,并且实现了对被代理对象的功能的增强。
  • 四、动态代理
    静态代理模式可以解决对业务逻辑进行增强需求的满足,但是会有一个问题,就是如果还有别的功能需要扩展,则需要新增新的代理类,随着需求越来越多,代理类也会越来越多。
    而动态代理技术则是通过动态生成java字节码的方式,将生成的字节码加载进ClassLoad,生成对应的Class对象,在通过Class对象生成普通java对象的。
    从而解决代理类数量爆炸的问题。
    下面我们就从代码层面讲解java的两种动态代理技术:
    • 1、jdk动态代理

      • 代码
        public static void main(String[] args) {
        Hello hello = new HelloImpl();
        //        Hello helloProxy = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class[]{Hello.class}, new InvocationHandler() {
        //            @Override
        //            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //                System.out.println("proxy method begin");
        //                Object ret = method.invoke(hello, args);
        //                System.out.println("proxy method end");
        //                return ret ;
        //            }
        //        });
        
        Hello helloProxy = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class[]{Hello.class},
                (proxy, method, as) -> {
                 System.out.println("proxy method begin");
                Object ret = method.invoke(hello, as);
                System.out.println("proxy method end");
                return ret ;
                });
        hello.sayHello();
        System.out.println("=================below is dynamic proxy mode====================");
        helloProxy.sayHello();
        

      }
      ```

      • 结果
        hello, world
        =================below is dynamic proxy mode====================
        proxy method begin
        hello, world
        proxy method end
        
        可以看出,jdk的动态代理有一个关键点,就是接口,只有被代理对象实现了接口的时候,jdk动态代理才可以通过实现相同接口的方式来进行代理对象的生成,从而实现功能的扩展。那么,如果需要被代理的对象
    • 2、cglib代理

      • 代码
        public static void main(String[] args) {
        HelloImpl hello = new HelloImpl();
        
        hello.sayHello();
        
        System.out.println("=================below is cglib proxy mode====================");
        
        Enhancer enhancer = new Enhancer();
        enhancer.setClassLoader(hello.getClass().getClassLoader());
        enhancer.setSuperclass(HelloImpl.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("proxy method begin");
                Object ret = method.invoke(hello, objects);
                System.out.println("proxy method end");
                return ret;
            }
        });
        
        HelloImpl helloCglibProxy = (HelloImpl) enhancer.create();
        helloCglibProxy.sayHello();
        
        

      }
      ```

      • 结果
        hello, world
        =================below is cglib proxy mode====================
        proxy method begin
        hello, world
        proxy method end
        
        可以看到,cglib代理的实现方式与jdk动态代理是完全不同的,究其原理来说,jdk动态代理是通过实现接口的方式来实现代理对象的生成,而cglib代理,不需要接口,它是通过继承的方式来实现代理对象的生成。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值