Article directory
Last time we talked about registering and waking up beanfactory postprocessor, this time we will talk about the registration of BeanPostProcessor.
registerBeanPostProcessors()
Step 1: add BeanPostProcessorChecker
There are two parameters to create the BeanPostProcessorChecker: one is beanFactory, and the other is count.
This count represents the number of beanpostprocessors in the current environment.
The function of BeanPostProcessorChecker is to log the loaded BenPostProcessor. Relatively simple
//Find all BeanPostProcessor names in beanFactory String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); //Number of existing beanpostprocessors + self + registered beanpostprocessors int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
Step 2: sort the implementation classes of BeanPostProcessor
That is to say, the previous sorting for BeanFactoryPostProcessor is the same, but there is something special here.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();//Priority queue List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();//Add a new one, mainly dealing with some internal situations of Bean (@ Value,@AutoWrite similar) List<String> orderedPostProcessorNames = new ArrayList<>(); //Sort queue List<String> nonOrderedPostProcessorNames = new ArrayList<>();//Common queue 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); } }
Here we can see that it is divided into four sets, namely:
- Priority queue with PriorityOrdered implemented
- Implement the bean definition merge queue of MergedBeanDefinitionPostProcessor
- Implement Ordered sorting queue
- A normal queue without anything
The registration order is 1, 3 and 4 respectively.
Careful students here may have found that in the above code, the MergedBeanDefinitionPostProcessor can only be judged if the priority ordered condition is met. So do you think you have to implement PriorityOrdered?
The answer, of course, is No. It will be judged when the other two types of queues are processed later. In this way, there is order in the MergedBeanDefinitionPostProcessor dimension.
Step 3: register priority queue
sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
Step 4: register the sorting queue
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);
Step 5: register the normal queue
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);
Step 6: register and implement the queue of MergedBeanDefinitionPostProcessor
sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors);
Step 7: register the ApplicationListenerDetector
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
The function of the ApplicationListenerDetector class is to find out the single instance of ApplicationListener implemented in all beans and put it into the Listener collection of the container. This is also the second way to customize the Listener.
MergedBeanDefinitionPostProcessor
MergedBeanDefinitionPostProcessor is a special extension point that inherits BeanPostProcessor.
It allows developers to modify the Bean creation template before creating a Bean.
For example, we are familiar with @ autowritten auto assembly annotation.
Its processing class, Autowired annotation beanpostprocessor, implements MergedBeanDefinitionPostProcessor.
The main function is to put the attributes that need to be assembled into the bean definition for later filling (filling will be explained in detail in the later chapter getBean).
Another annotation is @ Resource
Its processing idea of common annotation bean processor is basically the same as the above.
I won't list the others one by one. As long as it's related to the filling of properties or methods during Bean creation, most of the solutions are related to MergedBeanDefinitionPostProcessor.
summary
Let's summarize the process of registering BeanPostProcessor
- Add a logging processor
- Sort the BeanPostProcess
- Register beanposoprocessor in order
- Add a processor to handle ApplicationListener