读书人

动态署理双剑客-JDK Proxy与CGLIB

发布时间: 2013-10-08 16:46:23 作者: rapoo

动态代理双剑客--JDK Proxy与CGLIB

背景:

研究过设计模式的同胞们都知道代理模式可以有两种实现方案:


1.接口实现(或继承抽象类)

动态署理双剑客-JDK Proxy与CGLIB

核心代码片段

ProxySubject-->>doOperation()

2.继承父类

动态署理双剑客-JDK Proxy与CGLIB

核心代码片段

ProxySubject-->>doOperation()

总结:

相同点

都可以通过Proxy控制对Target的访问

不同点

1.灵活性

“接口实现”的方式更加灵活,代理类可以代理所有实现了ISubject接口的类;

“继承父类”的方式代理类只能代理它的父类,因为java中只支持单继承

2.可行性

如果Target有直接接口,那么这两种方式都可以;

如果没有实现任何接口,那只能采取“继承父类”的方式了




正文


Java中动态代理对应着也有两种实现方式


1.“接口实现"---JDK Proxy

用到JDK提供的InvocationHandler接口和Proxy类


类之间的关系如下

动态署理双剑客-JDK Proxy与CGLIB

InvocationHandler接口

用于处理方法请求

Proxy类

用于生成代理对象


代码演示

ISubject接口

RealSubject类

LogHandler类

为了更明确的说明动态代理的工作原理,将代理的创建过程放到了LogHandler的外部,即main方法中

客户端类Client



调用过程时序图


动态署理双剑客-JDK Proxy与CGLIB




2.“继承父类”---CGLIB

用到了CBLIB提供的Enhancer类和MethodInterceptor接口


类之间的关系如下

动态署理双剑客-JDK Proxy与CGLIB

需要引入第三方jar包

cglib-2.2.jarasm-3.1.jar

Enhancer类

用于创建代理对象

MethodInterceptor接口

用于处理方法请求

代码演示

ISubject接口,RealSubject类同上

LogIntercept类


客户端类Client



调用过程时序图

动态署理双剑客-JDK Proxy与CGLIB


总结

大家可以看到JDK Proxy和CGLIB这两种动态代理的实现过程是非常相似的,但也有区别

相同点:

  • 都用到了一个接口一个类;
    • 接口用于处理方法调用,类用于创建代理对象

      JDK Proxy

      InvocationHandler接口

      Proxy类

      CGLIB

      MethodIntercept接口

      Enhancer类

      不同点:

      JDK Proxy

      使用目标类的接口创建动态代理

      CBLIB

      使用目标类的子类创建动态代理

      最后

      JDK Proxy和CGLIB两种动态代理各有千秋,具体用哪个方案要看具体情况。如果目标类实现了对应接口,两种方案都可以;如果没有实现任何接口则要使用CBLIB。比如Hibernate中的实体类是POJO类,没有实现任何接口,那么要通过代理实现延迟加载就只能采用CGLIB方案了。





      2楼wwwwenhuan5小时前
      自己对JDK Proxy和CGLIB的对比
      1楼caozhangyingfei01096小时前
      恩,名字挺帅

读书人网 >其他相关

热点推荐