Spring framework reference 2.0.5 reference manual Chinese Version 6.6. this is written in proxy mechanism
In Spring AOP, JDK dynamic proxy or cglib is used to create a proxy for the target object. (JDK dynamic proxy is recommended as much as possible)
If the target object to be proxy implements at least one interface, JDK dynamic proxy is used. All interfaces implemented for this target type will be proxies. If the target object does not implement any interfaces, A cglib proxy is created.
If you want to force cglib proxy (for example, you want to proxy all methods of the target object, not just methods that implement self-interfaces), you can. However, you need to consider the following issues:
- Cannot be notified (advise)
Final
Method because they cannot be overwritten.
- You need to put the cglib 2 binary distribution package under classpath. Compared with JDK, it provides dynamic proxy.
To use the cglib proxy forcibly<aop:config>
Ofproxy-target-class
Set property to true:
<aop:config proxy-target-class="true">...</aop:config>
If you need to use cglib proxy and @ aspectj automatic Proxy Support, set it as follows:<aop:aspectj-autoproxy>
Ofproxy-target-class
Attribute:
<aop:aspectj-autoproxy proxy-target-class="true"/>
In actual use, the difference in details is discovered,The dedevil is in the detail.
JDK dynamic Proxy: the proxy object must be the implementation of an interface. It is the proxy of the target object by creating an interface implementation class during running.
Cglib Proxy: The implementation principle is similar to JDK dynamic proxy, but the proxy object generated during running is a subclass of the target class extension. Cglib is an efficient code generation package. At the underlying layer, cglib relies on ASM (open-source Java bytecode editing class library) to operate on bytecode, which has better performance than JDK.
What does spring rely on to determine which proxy policy is used to generate the AOP proxy? The following code is the judgment logic of spring.
// Org. springframework. AOP. Framework. defaultaopproxyfactory
// The advisedsupport parameter is a class related to Spring AOP configuration.
Public aopproxy createaopproxy (advisedsupport)
Throws aopconfigexception {
// Determine whether to use JDK dynamic proxy or cglib proxy
If (advisedsupport. isoptimize () | advisedsupport. isproxytargetclass ()
| Hasnousersuppliedproxyinterfaces (advisedsupport )){
If (! Cglibavailable ){
Throw new aopconfigexception (
"Cannot proxy target class because cglib2 is not available ."
+ "Add cglib to the class path or specify proxy interfaces .");
}
Return cglibproxyfactory. createcglibproxy (advisedsupport );
} Else {
Return new jdkdynamicaopproxy (advisedsupport );
}
}
Advisedsupport. isoptimize () and advisedsupport. isproxytargetclass () returns false by default. Therefore, whether or not the target object implements an interface determines the policy adopted by spring by default. Of course, you can set advisedsupport. isoptimize () or advisedsupport. isproxytargetclass () returns true, so that cglib proxy is used no matter whether the target object implements the interface spring. Therefore, by default, if a target object implements the spring interface, the JDK dynamic proxy policy will be used to dynamically create an interface implementation class (Dynamic proxy class) to proxy the target object, this dynamic proxy class is another version of the target object. Therefore, Java is thrown during forced conversion between the two. lang. classcastexception. By default, if the target object does not implement any interfaces, spring selects the cglib proxy, and the generated dynamic proxy object is a subclass of the target class.
By default, you can also manually configure some options to use cglib proxy for spring.
Org. springframework. transaction. interceptor. transactionproxyfactorybean is Org. springframework. AOP. framework. proxyconfig subclass, so you can refer to some settings in proxyconfig as follows, set optimize and proxytargetclass to true, you can force spring to use cglib proxy.
If you need to use cglib proxy and @ aspectj automatic Proxy Support, set the proxy-target-class attribute of <AOP: aspectj-autoproxy> as follows:
<AOP: aspectj-autoproxy proxy-target-class = "true"/>
In this way, the cglib proxy will not cause the classcastexception problem mentioned above, and the performance can be improved. The key is whether the proxy object inherits the interface and can be used in a unified manner.