spring source code: register post processor

purpose

When programmers extend spring, they can implement post-processors themselves to complete specific business operations. This blog is mainly to learn how spring adds post-processors provided by programmers to spring containers;
incidentally, Make a rough analysis and introduction of several other methods in the spring initialization process

Source code learning

registerBeanPostProcessors(beanFactory);

This method is used to complete, register the BeanPostProcessor implementation class.
If we implement the BeanPostProcessor interface and provide our own business processing logic, spring will first instantiate the BeanPostProcessor implementation class we provide before instantiating the business bean. , And stored in a specific collection;

org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors

This method is used to process the post processor.
So: This method boils down to two things.

  1. Initialize all BeanPostProcessors (including spring's own + ours) and store them in the spring container (signletonObjects collection)
  2. Store all BeanPostProcessors in a list ( private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();)
public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

  /**
 * 1.获取到所有实现了beanPostProcessor接口的实现类的name,从beanDefinitionMaps中获取
 *  这里在从BeanDefinitionMap中获取BeanPostProcessor类型的实现类的时候,会进行bean的合并,也即:将bean转换Wie
   */
  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.
  /**
 * 2.internalPostProcessors:存储的是实现了MergedBeanDefinitionPostProcessor接口的实现类
 * 这里没想明白为什么要把实现了该接口的实现类单独存储
   */
  List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
  List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
  List<String> orderedPostProcessorNames = new ArrayList<>();
  List<String> nonOrderedPostProcessorNames = new ArrayList<>();
  /**
 * 3.按照后置处理器实现的ordered接口 分别存到不同的集合中
   */
  for (String ppName : postProcessorNames) {
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      /**
       * 4.在调用getBean的时候,就会调用对应的初始化方法,完成对beanPostProcessor的初始化
       */
      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);
  /**
 * 5.registerBeanPostProcessors:该方法,就是把入参中的beanPostProcessor实现类存入到beanPostProcessors这个list集合中
   */
  registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

  // Next, register the BeanPostProcessors that implement Ordered.
  List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
  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<>();
  for (String ppName : nonOrderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    nonOrderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
      internalPostProcessors.add(pp);
    }
  }
  registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

  sortPostProcessors(internalPostProcessors, beanFactory);
  registerBeanPostProcessors(beanFactory, internalPostProcessors);

  beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

The logic here is relatively simple, but there are a few points to note:

  • At the first point: when the implementation class of beanPostProcessor is obtained from beanDefinitionMap, beanDefinition will be merged once (the beanDefinition is merged into RootBeanDefinition, the merged bean here will be explained in the following blog, just remember it for the time being)
  • When all the BeanPostProcessor implementation classes are obtained, the implementation classes will be classified by priority, and PriorityOrdered> Ordered> Ordinary Implementation Classes are implemented.
  • registerBeanPostProcessors(beanFactory, internalPostProcessors); This method is to put the instantiated BeanPostProcessor implementation class into the beanPostProcessors collection
  • When the getBean() method is called, it will try to get the bean from the single-instance pool. If the bean does not exist, it will be initialized and instantiated; that is: at point 4 in the source code, the beanPostProcessor will be instantiated (meaning That is to say: after the fourth point, the beanPostProcessor provided by ourselves and spring's own post processor have gone through the entire life cycle process, and it is a qualified bean)

initMessageSource();

I haven’t had time to look at this method yet. Baidu took a look and said it was used for internationalization, message binding, etc., and I will add it later after learning.

initApplicationEventMulticaster();

In this method, a multi-event dispatcher ApplicationEventMulticaster is initialized for event publishing

onRefresh();

This is an extension method. It is an empty method in the spring framework and is left for subinterfaces to be extended. Among them, the method is extended in the source code of springboot startup.

registerListeners();

Look at the name, it is used to register the event listener, I haven't learned it yet

finishBeanFactoryInitialization(beanFactory);

This is an important method to complete bean instantiation, and each core method in this method will be introduced later

finishRefresh();

After completing the initialization of spring, publish the ContextRefreshedEvent event. Of course, there are other operations. This method does not have to do too much learning. I will add it later.

Next, what I mainly want to share is the finishBeanFactoryInitialization method. In this method, spring initializes the scanned beanDefinition to the corresponding bean and stores it in the core method of the spring container.

Guess you like

Origin blog.csdn.net/CPLASF_/article/details/107302606