Dynamic Proxy of JDK and Cglib

来源:互联网 发布:金庸群侠传mac版 编辑:程序博客网 时间:2024/06/07 04:51

1. JDK

动态生成Class来实现target的所有接口,具体实现为nvocationHandler的invoke。


2. Cglib

动态生成Class来继承target,具体实现方法分两种:

一: 与原实现方法同名的,实现为Custom CALLBACKS>THREAD_CALLBACKS>STATIC_CALLBACKS的顺序去调用对应的intercept方法

二: 修改原实现方法名字为类似CGLIB$Method_Name$0, 实现为直接调用super class(即:target 对应的class)


3. 比较

JDK有实现相对简单,有不少缺点:

a. target必须实现接口

b. target本身的方法之间调用不会触发nvocationHandler的invoke方法,这是因为jdk本身设计上的缺陷,在写横切逻辑时,我们是直接用的target去调用对应的方法,因此内部调用还是target类本身,与Proxy没有任何关系。这也直接导致spring aop有同样的问题


Cglib实现相对复杂,JDK提到的缺点都是Cglib的优点:

a. Cglib采用的extends方式

b. Cglib在写横切逻辑时,一般写法是proxy.invokeSuper(obj, args); 这里的invokeSuper会调用之前提到的CGLIB$Method_Name$0,从而间接的调用了target的实现方法,但是此时所处的对象仍然是Proxy。所以调用本身的其他方法时会调用被proxy override的同名method(这是由于jvm的动态分派 invokevirtual 指令),因此又会触发Custom CALLBACKS。