cglib动态代理实现及其原理浅析
Posted 八阿哥克星
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cglib动态代理实现及其原理浅析相关的知识,希望对你有一定的参考价值。
JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。
举例:
1、定义被代理类:
public class CglibOrigin
public CglibOrigin()
System.out.println("CglibOrigin对象创建");
public final void finalMethod()
System.out.println("final方法执行");
public void regularMethod()
System.out.println("regularMethod方法执行");
2、定义拦截器,用以拦截被代理对象的方法(需要实现MenthodInterceptor接口)
public class MyMethodInterceptor implements MethodInterceptor
//Object o——生成的代理对象
//Method——被代理对象的方法
//Object[] objects——方法的参数
//methodProxy——代理方法
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable
System.out.println("======插入前置通知======");
((CglibOrigin)o).regularMethod();
Object object = methodProxy.invokeSuper(o, objects);
System.out.println("======插入后者通知======");
return object;
其中intercept()就是代理对象调用到方法时执行到的代码,即实现增强的代码部分;
而methodProxy.invokeSuper(o, objects)是执行被代理对象的方法;
3、测试
public class MyTest
@Test
public void test()
Enhancer enhancer = new Enhancer();
//设置被代理类class
enhancer.setSuperclass(CglibOrigin.class);
//设置回调对象即拦截器
enhancer.setCallback(new MyMethodInterceptor());
//生成代理对象
CglibOrigin origin = (CglibOrigin)enhancer.create();
//调用方法
origin.regularMethod();
这里的origin.regularMethod()方法,其实就是执行MyMethodInterceptor的intercept()。
生成的代理对象内部是这样的:
public final void sayHello()
//enhancer中赋值给callback的拦截器对象
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; if (var10000 == null) CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_0;
if (var10000 != null)
//调用拦截器MethodInterceptor的interceptor方法,完成增强
var10000.intercept(this, CGLIB$sayHello$0$Method, CGLIB$emptyArgs, CGLIB$sayHello$0$Proxy);
else
super.sayHello();
需要特别注意的是,CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。
(普通方法可以增强)
(final修饰的方法不可以增强)
jdk和cglib动态代理原理上的区别:
java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
以上是关于cglib动态代理实现及其原理浅析的主要内容,如果未能解决你的问题,请参考以下文章