[spring learning notes] registerBeanPostProcessors()

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:

  1. Priority queue with PriorityOrdered implemented
  2. Implement the bean definition merge queue of MergedBeanDefinitionPostProcessor
  3. Implement Ordered sorting queue
  4. 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

  1. Add a logging processor
  2. Sort the BeanPostProcess
  3. Register beanposoprocessor in order
  4. Add a processor to handle ApplicationListener
Published 6 original articles, praised 0, visited 45
Private letter follow

Posted by Adastra on Tue, 21 Jan 2020 10:33:05 -0800