前言
前文学习了jdk动态代理,这里记录一下cglib动态代理
一、为什么要有CGLIB动态代理
我们不是已经有了JDK动态代理嘛,为啥还要又cglib动态代理呀?
JDK动态代理统一有一个父类Proxy,Java单继承的特点导致它无法再代理class了,所以只能代理interface了。
CGLIB就解决了class的动态代理问题。
二、CGLIB简介
CGLIB是一个强大的高性能高质量的Code生成类库,它可以再运行期扩展Java类实现Java接口。也被广泛的应用于AOP的使用。
cglib底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。
三、CGLIB动态代理实现
cglb不是jdk自带的,所以需要引入一个包cglib
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.12</version>
</dependency>
Enhancer 就像描述的那样,是JDK动态代理的替代品,它既可以代理class也可以代理接口,但需要注意的是它不能拦截final方法。
MethodInterceptor extends Callback,它也属于回调,它里面的intercept的四个参数分别代表:要被代理的对象、被拦截的方法、被拦截方法的参数、触发父类的方法对象。
和JDK动态代理的区别是,调用方法采用的是MethodProxy的invokeSuper调用,其余的和JDK动态代理的一样。
/**
* 获取代理对象
*
* @return
*/
public Object getProxyInstance2() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetClass);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object result = null;
//要被代理的方法名称集合
//如果当前方法名处于这个集合中,说名这个方法需要代理调用
if (transactionalMethods.contains(method.getName())) {
//方法前置处理
result = methodProxy.invokeSuper(o, objects);
//方法后置处理
} else {
//否则,直接调用
result = methodProxy.invokeSuper(o, objects);
}
return result;
}
});//回调,就是要拦截的东西
//得到代理对象
Object result = enhancer.create();
return result;
}
更详细的比如回调过滤、对象整合等等就不介绍了,项目中如有遇到,再进行记录。
总结:
基于ASM操作字节码实现的,相对JDK动态代理的代理范围要更完善,性能更高,不过需要注意的是,这些字节码文件也是会被放在JVM内存中的,要注意OOM异常。