- 静态代理
- 动态代理
- JDK动态代理
- cglib动态代理
- jdk动态代理和cglib的比较
静态代理
静态代理相对来说比较简单,无非就是聚合+多态:
动态代理
通过使用代理,我们可以在被代理的类的方法的前后添加一些处理方法,例如事务,日志等。这样就达到了类似AOP的效果,而JDK中提供的动态代理,就是实现aop的绝好底层技术。
JDK动态代理
JDK动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。InvocationHandler是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编制在一起。
Proxy利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象。
CGLib动态代理
还有一个叫CGLib的动态代理,CGLib全称为Code Generation Library,是一个强大的高性能,高质量的代码生成类库,可以在运行期扩展Java类与实现Java接口,CGLib封装了asm,可以再运行期动态生成新的class。和JDK动态代理相比较:JDK创建代理有一个限制,就是只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,则可以通过CGLib创建动态代理。
首先是两个测试类:
接下来演示CGLib的使用:
CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势织入横切逻辑。
JDK动态代理和CGLib的比较
CGLib所创建的动态代理对象的性能比JDK所创建的代理对象性能高不少,大概10倍,但CGLib在创建代理对象时所花费的时间却比JDK动态代理多大概8倍,所以对于singleton的代理对象或者具有实例池的代理,因为无需频繁的创建新的实例,所以比较适合CGLib动态代理技术,反之则适用于JDK动态代理技术。另外,由于CGLib采用动态创建子类的方式生成代理对象,所以不能对目标类中的final,private等方法进行处理。所以,大家需要根据实际的情况选择使用什么样的代理了。
同样的,Spring的AOP编程中相关的ProxyFactory代理工厂内部就是使用JDK动态代理或CGLib动态代理的,通过动态代理,将增强(advice)应用到目标类中。