spring aop动态代理

一、何为动态代理?动态代理相对于aspectJ静态代理有何优势?

二、spring aop动态代理

2.1
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。

2.2
如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,是利用asm开源包,可以在运行时动态的生成某个类的子类。注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

2.3 spring,spring boot与CGLIB版本兼容性问题说明

1)从Spring 3.2以后不再将CGLIB放在项目的classpath下,而是将CGLIB类打包放在spring-core下面的org.springframework中。这个就意味着基于CGLIB的动态代理与JDK的动态代理在可以直接使用。

2)在Spring 4.0中,因为CGLIB代理实例是通过Objenesis创建的,所以代理对象的构造器不再有两次调用。

3)在 Spring Boot 2.0 中,Spring Boot现在默认使用CGLIB动态代理(基于类的动态代理), 包括AOP. 如果需要基于接口的动态代理(JDK基于接口的动态代理) , 需要设置spring.aop.proxy-target-class属性为false。
spring aop动态代理
2.4 源码分析

org.springframework.aop.framework

spring aop动态代理
2.5 总结
1)java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理

cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理

2)JDK动态代理只能对实现了接口的类生成代理,而不能针对类
为什么JDK动态代理必须要实现接口?
因为****java的单继承,动态生成的代理类已经继承了Proxy类,****就不能再继承其他的类,要与代理类联系起来,只能实现接口
CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承)

3)JDK动态代理与Cglib动态代理效率****比较?
jdk1.7之前JDK动态代理的效率要低于Cglib,但jdk1.7之后,java做了优化JDK动态代理的效率要高于Cglib
虽然后来优化后JDK动态代理效率要高于Cglib,但并不是反射的效率要高于操作字节码。
操作字节码要效率远高于反射

2.5 两种代理模式优缺点

1.若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。
优点:因为有接口,所以使系统更加松耦合
缺点:为每一个目标类创建接口
2.若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。
优点:因为代理类与目标类是继承关系,所以不需要有接口的存在。
缺点:因为没有使用接口,所以系统的耦合性没有使用JDK的动态代理好。

上一篇:Spring mvc mybatis cxf Add CGLIB to your classpath. 错误


下一篇:class net.sf.cglib.core.DebuggingClassWriter overrides final method visit