Article directory
- 1. Debug analysis AnnotationAwareAspectJAutoProxyCreator execution process
-
- 1. Call the refresh() method in the AnnotationConfigApplicationContext class
- 2. Call the registerBeanPostProcessors(beanFactory) method in the refresh() method
- 3. Call the PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this) method in the registerBeanPostProcessors() method
- 4. Call the registerBeanPostProcessors(beanFactory, this) method in PostProcessorRegistrationDelegate
- 5. Call the getBean() method in AbstractBeanFactory
- 6. Call the doGetBean() method in AbstractBeanFactory
- 7. Call the getSingleton() method in DefaultSingletonBeanRegistry
- 8. Call the createBean() method in the doGetBean() method
- 9. Call the createBean() method in AbstractAutowireCapableBeanFactory
- 10. Call the doCreateBean() method in AbstractAutowireCapableBeanFactory
- 11. Call the initializeBean() method in AbstractAutowireCapableBeanFactory
- 12. After the bean is initialized, roll back the method stack to the getSingleton() method
- 13. Finally, fall back to registerBeanPostProcessors and continue to register the next BeanPostProcessors
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:
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
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
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
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:
- First get all BeanPostProcessors that have been defined in the IOC container
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.
- 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.
- 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.
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.
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.
Then register all the regular beanPostProcessors.
Finally, re-register all internal BeanPostProcessors.
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.).
Back to the logic executed in the method stack
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.
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.
7. Call the getSingleton() method in DefaultSingletonBeanRegistry
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
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
10. Call the doCreateBean() method in AbstractAutowireCapableBeanFactory
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)
After executing createBeanInstance(), execute populateBean(), initializeBean()
The process of doCreateBean():
- First createBeanInstance() creates an instance of the bean
- Then populateBean() assigns values to various properties of the bean
- 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
Next, analyze in detail the process of initializing beans
(1) Execute the invokeAwareMethods() method
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
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
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
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
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?
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.
(4) Execute the postProcessAfterInitialization() method
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
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
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.
Finally, call the addBeanPostProcessor() method of beanFactory to register all created BeanPostProcessors in BeanFactory.