Article directory
1. @EnableAspectJAutoProxy annotation description
Add the @EnableAspectJAutoProxy annotation to the configuration class to enable the AOP function of the annotation version. In other words, if you want to use the annotation version of the AOP function in AOP, you need to add the @EnableAspectJAutoProxy annotation to the configuration class. Let's first look at the source code of the @EnableAspectJAutoProxy annotation, as follows:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
As can be seen from the source code, @EnableAspectJAutoProxy uses the @Import annotation to introduce the AspectJAutoProxyRegister.class object. So, what is AspectJAutoProxyRegistrar? We continue to click into the source code of the AspectJAutoProxyRegistrar class, as follows:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
You can see that the AspectJAutoProxyRegistrar class implements the ImportBeanDefinitionRegistrar interface. Look at the definition of the ImportBeanDefinitionRegistrar interface, as follows:
public interface ImportBeanDefinitionRegistrar {
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
registerBeanDefinitions(importingClassMetadata, registry);
}
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
}
}
ImportBeanDefinitionRegistrar interface function: You can add custom components to the IOC container through the ImportBeanDefinitionRegistrar interface.
In other words, the @EnableAspectJAutoProxy annotation uses the AspectJAutoProxyRegistrar object to customize the component and add the corresponding component to the IOC container.
2. Debug @EnableAspectJAutoProxy source code
Set a breakpoint in the registerBeanDefinitions() method of the AspectJAutoProxyRegistrar class, as follows:
Next, we use the debug method to run the testAop01() method of the AopTest class. After running, the program enters the breakpoint position, as shown below:
It can be seen that the program has been suspended at the breakpoint, and the call stack of the method is displayed in the lower left corner of IDEA.
In the registerBeanDefinitions() method of the AspectJAutoProxyRegistrar class, first call the registerAspectJAnnotationAutoProxyCreatorIfNecessary() method of the AopConfigUtils class to register the registry. Just looking at the registerAspectJAnnotationAutoProxyCreatorIfNecessary() method is not difficult to understand. The literal meaning is: register an AspectJAnnotationAutoProxyCreator if necessary.
Next, we enter the registerAspectJAnnotationAutoProxyCreatorIfNecessary() method of the AopConfigUtils class, as follows:
In the registerAspectJAnnotationAutoProxyCreatorIfNecessary() method of the AopConfigUtils class, the overloaded registerAspectJAnnotationAutoProxyCreatorIfNecessary() method is directly called, and we continue to follow the code, as shown below:
You can see that the registerOrEscalateApcAsRequired() method is directly called in the overloaded registerAspectJAnnotationAutoProxyCreatorIfNecessary() method. In the registerOrEscalateApcAsRequired() method, the AnnotationAwareAspectJAutoProxyCreator.class object is passed in.
Let's move on to the code as follows:
We can see that in the registerOrEscalateApcAsRequired() method, the type of the Class object received is: org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.
In the registerOrEscalateApcAsRequired() method, first determine whether the registry contains a bean of type org.springframework.aop.config.internalAutoProxyCreator. As follows:
If the bean of type org.springframework.aop.config.internalAutoProxyCreator is included in the registry, corresponding processing is performed. From the source code of Spring, the bean of type org.springframework.aop.config.internalAutoProxyCreator is taken out of the registry, and Determine whether the name value of the cls object is equal to the beanClassName value of the apcDefinition. If they are not equal, get the priority of apcDefinition and cls, if the priority of apcDefinition is less than that of cls, set the beanClassName of apcDefinition to the name value of cls. Relatively speaking, it is relatively simple to understand.
We are running the program for the first time here, and we will not enter the if condition. Let's continue to look at the code, as shown below:
Here, use RootBeanDefinition to create a beanDefinition, and pass in the Class object of org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator as a parameter.
Let's continue to look at the code. In the registerOrEscalateApcAsRequired() method of the AopConfigUtils class, the registerBeanDefinition() method will be called to register the component through the registry, as shown below:
And the name of the registered bean is org.springframework.aop.config.internalAutoProxyCreator.
Next, let's continue to look at the registerBeanDefinitions() source code of the AspectJAutoProxyRegistrar class, as follows:
Use the attributesFor method of the AnnotationConfigUtils class to obtain the information of the @EnableAspectJAutoProxy annotation. Next, judge whether the value of the proxyTargetClass property is true, and if it is true, call the forceAutoProxyCreatorToUseClassProxying() method of the AopConfigUtils class; continue to judge whether the value of the exposeProxy property is true, and if it is true, call the forceAutoProxyCreatorToExposeProxy() method of the AopConfigUtils class.
In summary, after adding the @EnableAspectJAutoProxy annotation to the Spring configuration class, the AnnotationAwareAspectJAutoProxyCreator will be registered with the IOC container.
Next, let's look at the structure diagram of the AnnotationAwareAspectJAutoProxyCreator class
Let's briefly sort out the core inheritance relationship of the AnnotationAwareAspectJAutoProxyCreato class, as follows:
AnnotationAwareAspectJAutoProxyCreator
-> AspectJAwareAdvisorAutoProxyCreator (parent class)
-> AbstractAdvisorAutoProxyCreator (parent class)
-> AbstractAutoProxyCreator (parent class)
implements SmartInstantiationAwareBeanPostProcessor, BeanFactory Aware (two interfaces)
Looking at the inheritance relationship, it can be found that this class implements the Aware and BeanPostProcessor interfaces, both of which are related to the initialization of Spring beans, so it is speculated that the main processing methods of this type come from the implementation methods of these two interfaces. At the same time, this class also implements the order method.
The detailed code and execution flow of the AnnotationAwareAspectJAutoProxyCreator class will be explained in the next chapter.