设计模式(四):代理模式之CGLIB动态代理(CGLIB Dynamic Proxy)
基于静态代理和动态代理需要绑定接口的局限性,而对类的代理在某些场景下确实是需要的,所以某些大牛就创造了CGLIB
这个动态代理类库。
CGLIB
底层是基本ASM
字节码处理框架,该库允许在程运行时对字节码进行修改和动态生成新的类。
CGLIB
所创建的动态代理对象的性能比JDK
所创建的动态代理对象的性能高(大概10倍),但CGLIB
在创建代理对象时所花费的时间却比JDK
动态代理多(大概8倍)。
对于singleton
的代理对象或者具有实例池的代理,因无须频繁创建对象,比较适用CGLIB
动态代理技术;反之则适合采用JDK
动态代理技术。
CGLIB
CGLIB 生成的动态代理,是在运行期间通过 Java 的反射机制,生成被代理目标类的子类,同时实现了net.sf.cglib.proxy.Factory
接口,这个接口是CGLIB
自己加入的。
CGLIB 是通过继承实现代理,所以被代理的目标类不能被final
关键字修饰,因为final
修饰的父类是不能被继承的;目标类的方法不能被final,static,private
修饰, final,static
的方法不能被重载,否则就不会被拦截, private
修饰不能被外部调用。
CGLIB 的核心是MethodInterceptor
接口,目标对象的所有方法都会转给MethodInterceptor.intercept()
方法来执行,该方法会拦截所有父类方法的调用,同时织入横切逻辑(在该方法里写增强的功能,如加入日志、安全检查等)。
使用步骤
- 业务类
- 创建
MethodInterceptor
接口的实现类(我称之为CGLIB工厂类),将目标类对象传入该工厂类的构造方法,新建一个创建代理对象的方法,重写intercept
方法,在该方法编写增强功能。 - 外部调用时生成CGLIB工厂类的对象,在构造方法里传入被代理的目标类对象,在工厂类对象调用方法创建代理对象并返回。
- 代理对象调用目标类的方法。
intercept方法
intercept(Object obj, Method method, Object[] paramArr, MethodProxy methodProxy)
方法解析
- Object obj:第一个参数表示目标类对象。
- Method method:第二个参数为目标为的反射对象。
- Object[] objArr:第三个参数为方法的参动入参。
- MethodProxy methodProxy:第四个参数为代理类对象。
示例代码
业务类
1 | /** |
CGLIB拦截类
1 | public class CglibInterceptor implements MethodInterceptor { |
客户端调用
1 | public class CGLIBMain { |
相关参考
设计模式(四):代理模式之CGLIB动态代理(CGLIB Dynamic Proxy)
http://blog.gxitsky.com/2018/03/16/DesignPatterns-04-Proxy-Cglib/