Original address:
Everyone knows that AOP uses the proxy mode. This article mainly introduces how to set up and distinguish the two proxy modes. After quoting some of the original text, I added my own understanding and a more in-depth elaboration:
1. The difference between the underlying implementation of JDK proxy and CGLIB proxy
* JDK proxy can only generate proxy by reflection for classes that implement interfaces , but not for classes, so it is also called "interface proxy"
* CGLIB is for classes to implement proxy, It mainly generates a subclass for the specified class in the form of bytecode conversion (ASM framework) , and overrides the methods in it.
[Note]: There are two special cases, static and final methods:
* JDK proxy can only generate proxy by reflection for classes that implement interfaces , but not for classes, so it is also called "interface proxy"
* CGLIB is for classes to implement proxy, It mainly generates a subclass for the specified class in the form of bytecode conversion (ASM framework) , and overrides the methods in it.
[Note]: There are two special cases, static and final methods:
Final method |
Static method |
|
Jdk agent |
The interface cannot use the final keyword, so it cannot be used. 【Error report】 |
After the interface method uses static , the proxy object will not be able to access this method, so it cannot be used. 【Error report】 |
Cglib proxy |
After the parent class method is final , the subclass cannot override it and cannot intercept it. [No error, but no interception] |
After the parent class method uses static , the subclass will not be able to rewrite it and cannot intercept it. [No error, but no interception] |
At the same time, when using cglib proxy, the target class must not be a final class (cannot be inherited), otherwise an error will be reported.
It can be seen from the above that when
using a
proxy, try not to use the final and static keywords .
Second, the deployment of two modes in Spring:
1. If the target object implements the interface , the dynamic proxy mechanism of the JDK will be used to implement AOP by default , but CGLIB can be forced to implement AOP ;
2. If the target object does not implement the interface , CGLIB must be used Generate proxy, spring will automatically switch between CGLIB and JDK dynamic proxy .
3. How to force proxy generation with CGLIB? * Add CGLIB library, <SPRING_HOME>/lib/cglib/*.jar (in fact, Spring's core package includes cglib-nodep-2.2.jar, or it will be )
1. If the target object implements the interface , the dynamic proxy mechanism of the JDK will be used to implement AOP by default , but CGLIB can be forced to implement AOP ;
2. If the target object does not implement the interface , CGLIB must be used Generate proxy, spring will automatically switch between CGLIB and JDK dynamic proxy .
3. How to force proxy generation with CGLIB? * Add CGLIB library, <SPRING_HOME>/lib/cglib/*.jar (in fact, Spring's core package includes cglib-nodep-2.2.jar, or it will be )
* Add to the spring configuration file:
<aop:aspectj-autoproxy proxy-target-class="true"/>
<aop:aspectj-autoproxy proxy-target-class="true"/>