As we all know, the underlying AOP is dynamic proxies, and there are two ways to implement dynamic proxies in Java:
- JDK-based dynamic proxy
- Dynamic proxy based on Cglib
The biggest difference between these two is that JDK-based dynamic proxies require the object being proxied to implement an interface, while Cglib-based dynamic proxies do not require the object being proxied to implement an interface.
So, how is AOP implemented in Spring? Is it a dynamic proxy based on JDK or a dynamic proxy based on Cglib?
1. Spring
Let’s start with the conclusion that dynamic proxies in Spring, which one to use, are divided into cases.
- If the proxy object implements the interface, then use the JDK dynamic proxy, otherwise it is the Cglib dynamic proxy.
- If the proxy object does not implement an interface, then it is a direct Cglib dynamic proxy.
Let’s take a look at the official documentation.
As you can see, even in the latest version of Spring, the strategy remains the same as above. That is, if you can use JDK to do dynamic proxy, use JDK, if you can’t use JDK to do dynamic proxy, use Cglib, that is, JDK is preferred to do dynamic proxy.
2. Spring Boot
Spring Boot and Spring are the same, so is it the same strategy for dynamic proxies? Sorry, it’s not really the same.
The handling of this issue in Spring Boot, with Spring Boot 2.0 as the node, is not the same.
Before Spring Boot 2.0, the code for automating the configuration of Aop looked like this (Spring Boot 1.5.22.RELEASE
)
|
|
As you can see, this automation configuration is mainly discussing the value of the spring.aop.proxy-target-class
property in the application.properties configuration file.
The @ConditionalOnProperty
annotation is what does the trick. To illustrate a few of the properties in this annotation.
- prefix: The prefix of the configuration file.
- name: the name of the configuration file, and prefix together form the key of the configuration.
- having: the value of the expected configuration. If the actual configuration is the same as the value of having, then the configuration will take effect, otherwise it will not.
- matchIfMissing: if the developer did not configure it in application.properties, then this configuration class will take effect or not.
Based on the introduction as above, it is easy to see that.
- If the developer has set
spring.aop.proxy-target-class
to false, then the JDK proxy is used. - If the developer has
spring.aop.proxy-target-class
set to true, then the Cglib proxy is used. - If the developer did not configure the
spring.aop.proxy-target-class
property in the first place, then the JDK proxy is used.
This was the case before Spring Boot 2.0.
Let’s look at the situation after Spring Boot 2.0 (inclusive) (Spring Boot 2.0.0.RELEASE
).
|
|
As you can see, most of the configuration is the same, with one area that is not quite the same, and that is the value of the matchIfMissing
property. As you can see, starting with Spring Boot 2.0, if the user does not configure anything, the Cglib proxy is used by default.
3. Practicing
Finally, let’s write a simple example to verify our ideas.
First create a Spring Boot project (in this case using the latest version of Spring Boot, i.e. using the Cglib proxy by default) and just add three dependencies, as follows.
|
|
Next we create an IUserService
interface, as follows.
Let’s then create an implementation class for that interface.
method does not need to be implemented.
Write another simple Aspect
.
Finally, write a simple test method that injects an instance of IUserService
.
Execute the test. With DBUEG, you can see that IUserService is proxied by Cglib.
If we want to use the JDK as a proxy, then we just need to add the following configuration to application.properties
.
|
|
After adding properties, re DEBUG. the result is as follows.
As you can see, the JDK dynamic proxy is already in use.
If you are using Spring Boot 1.5.22.RELEASE, then even if you don’t add configuration to application.properties
, the default is a JDK proxy. I won’t test this, but you can try it yourself if you are interested.
4. Summary
- AOP in Spring, if you have an interface, use the JDK dynamic proxy, no interface, use Cglib dynamic proxy.
- Spring Boot AOP, before 2.0 and Spring the same; 2.0 after the preferred Cglib dynamic proxy, if users want to use JDK dynamic proxy, you need to manually configure their own.