AOP principle - analysis @EnableAspectJAutoProxy annotation source code

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:

insert image description here

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:

insert image description here

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:

insert image description here

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:

insert image description here

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:

insert image description here

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:

insert image description here

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:

insert image description here

Here, use RootBeanDefinition to create a beanDefinition, and pass in the Class object of org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator as a parameter.

insert image description here

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:

insert image description here

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:

insert image description here

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

insert image description here

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.

Guess you like

Origin blog.csdn.net/qq_36602071/article/details/130001816