AOP principle - in-depth analysis of AnnotationAwareAspectJAutoProxyCreator registration process

1. Debug analysis AnnotationAwareAspectJAutoProxyCreator execution process

After running the IOCTest_AOP test class in debug mode, it will first come to the setBeanFactory() method of the AbstractAdvisorAutoProxyCreator class, as shown in the following figure:

insert image description here

insert image description here

In the figure above, the method call stack records the call process from the test01() test method to the setBeanFactory() method in AbstractAdvisorAutoProxyCreator

1. Call the refresh() method in the AnnotationConfigApplicationContext class

Execute the next step of the test01() test method and call the refresh() method in the AnnotationConfigApplicationContext class

insert image description here

2. Call the registerBeanPostProcessors(beanFactory) method in the refresh() method

Enter the refresh() method, the next step is to execute the registerBeanPostProcessors(beanFactory) method in the refresh() method

insert image description here

The function of the registerBeanPostProcessors(beanFactory) method is to register the bean's post-processor, which can intercept the creation of the bean

3. Call the PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this) method in the registerBeanPostProcessors() method

Then call the PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this) method in the registerBeanPostProcessors() method

insert image description here

4. Call the registerBeanPostProcessors(beanFactory, this) method in PostProcessorRegistrationDelegate

The complete code of PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this) method is as follows:

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    
    

	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// Register BeanPostProcessorChecker that logs an info message when
	// a bean is created during BeanPostProcessor instantiation, i.e. when
	// a bean is not eligible for getting processed by all BeanPostProcessors.
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// Separate between BeanPostProcessors that implement PriorityOrdered,
	// Ordered, and the rest.
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
	List<String> orderedPostProcessorNames = new ArrayList<>();
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
    
    
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    
    
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
    
    
				internalPostProcessors.add(pp);
			}
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    
    
			orderedPostProcessorNames.add(ppName);
		}
		else {
    
    
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// First, register the BeanPostProcessors that implement PriorityOrdered.
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// Next, register the BeanPostProcessors that implement Ordered.
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	for (String ppName : orderedPostProcessorNames) {
    
    
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
    
    
			internalPostProcessors.add(pp);
		}
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// Now, register all regular BeanPostProcessors.
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String ppName : nonOrderedPostProcessorNames) {
    
    
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
    
    
			internalPostProcessors.add(pp);
		}
	}
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// Finally, re-register all internal BeanPostProcessors.
	sortPostProcessors(internalPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, internalPostProcessors);

	// Re-register post-processor for detecting inner beans as ApplicationListeners,
	// moving it to the end of the processor chain (for picking up proxies etc).
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

Next, analyze the overall logic of the PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this) method in detail:

  1. First get all BeanPostProcessors that have been defined in the IOC container

insert image description here

You may ask, why are there some defined BeanPostProcessors in the IOC container? This is because when we created the IOC container earlier, we need to pass in the configuration class first, and when we parse the configuration class, because there is a @EnableAspectJAutoProxy annotation in the configuration class, we have also said that it will be for this annotation. We register an AnnotationAwareAspectJAutoProxyCreator (post-processor) in our container, which is just what the @EnableAspectJAutoProxy annotation does. In addition, there are some default post-processor definitions in the container.

So, when the program runs to this point, there are already some post-processors we will use in the container, but no objects have been created yet, and they are just some definitions, that is to say, which post-processors are in the container.

  1. Then execute beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

Registers a BeanPostProcessorChecker that logs a message when a bean is created during BeanPostProcessor instantiation, i.e. when the bean is not eligible to be processed by all BeanPostProcessors.

insert image description here

  1. Several collections will then be created to represent the separation between implementing PriorityOrdered, Ordered and other beanpostprocessors.
    That is, separate these BeanPostProcessors to see which ones implement the PriorityOrdered interface, which ones implement the Ordered interface, and which ones implement the interface natively.

insert image description here

It can be seen that the BeanPostProcessor will also be divided. If the BeanPostProcessor implements the PriorityOrdered interface, it will be saved in the List collection named priorityOrderedPostProcessors, and if the BeanPostProcessor is still of the type MergedBeanDefinitionPostProcessor, it must be saved. In the List collection named internalPostProcessors.

First, register BeanPostProcessors that implement PriorityOrdered.

insert image description here

Seen through the PriorityOrdered source code, PriorityOrdered inherits the Ordered interface. To further explain, those BeanPostProcessors in the IOC container are prioritized.

public interface PriorityOrdered extends Ordered {
    
    
}

Next, register BeanPostProcessors that implement Ordered.

insert image description here

Then register all the regular beanPostProcessors.

insert image description here

Finally, re-register all internal BeanPostProcessors.

insert image description here

Re-registers the post-processor used to detect the inner bean as an applicationListener, moving it to the end of the processor chain (for selecting proxies, etc.).

insert image description here

Back to the logic executed in the method stack

insert image description here

Why does the method stack stay here? Because the component named internalAutoProxyCreator (its type is AnnotationAwareAspectJAutoProxyCreator) to be created now implements the Ordered interface.

As you can see, you need to get the name of the BeanPostProcessor to be registered first, and then get it from the beanFactory.

5. Call the getBean() method in AbstractBeanFactory

Next, we will get the BeanPostProcessor with the corresponding name, how to get it? Continue to follow up the method call stack, as shown in the figure below, you can see that it is now located in the getBean() method of the AbstractBeanFactory abstract class.

insert image description here

6. Call the doGetBean() method in AbstractBeanFactory

The doGetBean() method is very long, so I won't analyze it in detail here, just pay attention to the line of code where the program stays. This line of code means to call the getSingleton() method to obtain a single-instance bean. However, this bean will not exist in the IOC container for the first time, so the bean will be created next.

insert image description here

7. Call the getSingleton() method in DefaultSingletonBeanRegistry

insert image description here

When the single instance bean cannot be obtained from the IOC container for the first time, the getObject() method of singletonFactory will be called

8. Call the createBean() method in the doGetBean() method

insert image description here

It can be seen that when the bean cannot be obtained from the IOC container for the first time, the createBean() method will be executed to create the bean.
Now it is necessary to create the AnnotationAwareAspectJAutoProxyCreator object and then save it in the container.

9. Call the createBean() method in AbstractAutowireCapableBeanFactory

insert image description here

10. Call the doCreateBean() method in AbstractAutowireCapableBeanFactory

insert image description here

The program stays here, and then prepares to initialize the bean, indicating that the bean instance has been created before this. In the doCreateBean() method, the createBeanInstance() method will be executed first to create a bean instance. (Because the order of creating beans is to instantiate the bean first and then initialize the bean)

insert image description here

After executing createBeanInstance(), execute populateBean(), initializeBean()

The process of doCreateBean():

  1. First createBeanInstance() creates an instance of the bean
  2. Then populateBean() assigns values ​​to various properties of the bean
  3. Then initializeBean() initializes the bean (this initialization bean is very important because the post-processor works before and after the bean is initialized).

11. Call the initializeBean() method in AbstractAutowireCapableBeanFactory

insert image description here

Next, analyze in detail the process of initializing beans

(1) Execute the invokeAwareMethods() method

insert image description here

In fact, this method is to judge whether the bean object implements the Aware interface. If it is, and it is one of the Aware interfaces BeanNameAware, BeanClassLoaderAware, and BeanFactoryAware, then call the relevant Aware interface method, that is, process Aware Interface method callbacks .

Now the current bean is called internalAutoProxyCreator (type AnnotationAwareAspectJAutoProxyCreator), which implements the BeanFactoryAware interface, so it will call the relevant Aware interface method, which is why the program stays in the invokeAwareMethods() method.

Then execute the callback method setBeanFactory() of the BeanFactoryAware interface

insert image description here

You can see that super.setBeanFactory(beanFactory) calls the setBeanFactory() method in the AbstractAdvisorAutoProxyCreator abstract class. What we want to create is the AnnotationAwareAspectJAutoProxyCreator object, but it is the setBeanFactory() method of its parent class that is called.

Continue to execute the initBeanFactory() method down

insert image description here

The initBeanFactory() method is used to initialize the BeanFactory. Enter the current method, as shown in the figure below, you can see that the initBeanFactory() method of the AnnotationAwareAspectJAutoProxyCreator class is called

insert image description here

You can see that the initBeanFactory() method creates two objects, one called ReflectiveAspectJAdvisorFactory, and the other called BeanFactoryAspectJAdvisorsBuilderAdapter, which is equivalent to repackaging the previously created aspectJAdvisorFactory and beanFactory.

(2) Execute the applyBeanPostProcessorsBeforeInitialization() method

insert image description here

After this method is called, it will return a wrapped bean.

The meaning of this method is actually to apply the postProcessBeforeInitialization() method of the post processor. We can go into this method to see how to apply the postProcessBeforeInitialization() method of the post processor?

insert image description here

It can be seen that it gets all the post-processors, and then calls the postProcessBeforeInitialization() method of the post-processor, which means that the post-processor is called here before the bean is initialized.

(3) Execute the invokeInitMethods() method

Implement a custom initialization method.

insert image description here

(4) Execute the postProcessAfterInitialization() method

insert image description here

Still get all the post-processors, and then call the postProcessAfterInitialization() method of the post-processor.

Therefore, the two postProcessBeforeInitialization() and postProcessAfterInitialization() methods of the post processor will be executed before and after the initialization method.

12. After the bean is initialized, roll back the method stack to the getSingleton() method

insert image description here

After the bean is initialized, roll back the method stack to the getSingleton() method, and finally add the created bean to the IOC container.

13. Finally, fall back to registerBeanPostProcessors and continue to register the next BeanPostProcessors

insert image description here

After AnnotationAwareAspectJAutoProxyCreator is registered in registerBeanPostProcessors, then continue to traverse the next BeanPostProcessors in the for loop to register. The process is consistent with the registration of AnnotationAwareAspectJAutoProxyCreator, and finally stored in the IOC container.

After the for loop is executed, continue to execute downward, and the sortPostProcessors() method will be called to sort these post-processors according to their priority.
If the program runs further down, it will call the registerBeanPostProcessors() method, and enter this method to have a look.

insert image description here

insert image description here

Finally, call the addBeanPostProcessor() method of beanFactory to register all created BeanPostProcessors in BeanFactory.

Guess you like

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