This is the 26th day of my participation in the August Text Challenge.More challenges in August

preface

Spring BeanFactoryPostProcessor interface invokeBeanFactoryPostProcessors method is mainly used for processing, RegisterBeanPostProcessors method is mainly used for processing the BeanPostProcessor interface.

BeanFactoryPostProcessor differs from BeanPostProcessor:

  • BeanFactoryPostProcessor is an extension to BeanFactory. It is used to read the bean definition and modify it before it is instantiated.
  • BeanPostProcessor BeanPostProcessor is an extension to beans that is used after bean instantiation and before and after initialization methods.

For example, AOP’s ability to generate proxies is to generate proxy objects after being instantiated by proxy classes.

Spring source code analysis series

  • Spring source code analysis – source code reading environment construction
  • Spring source Code analysis -IOC basic concepts
  • Spring source code analysis -IOC core components
  • Spring Source Code Analysis -IOC source code Analysis (1)
  • Spring IOC source code analysis -obtainFreshBeanFactory
  • Spring IOC source analysis – invokeBeanFactoryPostProcessors (3)

Source code analysis

RegisterBeanPostProcessors registers all the BeanPostProcessor, all achieved BeanPostProcessor class loading into the BeanFactory.

The BeanPostProcessor interface is an extension point exposed when Spring initializes beans. The Spring IoC container allows the BeanPostProcessor to add its own logical processing before and after the container initializes beans. In just register to the BeanFactory registerBeanPostProcessors method, the specific call is in bean initialization time.

registerBeanPostProcessors

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

   // 1. Find all classes that implement the BeanPostProcessor interface
   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.
   / / BeanPostProcessor counting
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   // 2. Add BeanPostProcessorChecker, which records information to BeanFactory
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   // 3. Define different variables to distinguish between the BeanPostProcessor of the PriorityOrdered, Ordered interface and the common BeanPostProcessor
   / / 3.1 priorityOrderedPostProcessors storage implementation PriorityOrdered BeanPostProcessor interface
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   // 3.2 internalPostProcessors stores Spring's internal BeanPostProcessor
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   / / 3.3 orderedPostProcessorNames storage realize Ordered BeanPostProcessor interface Name
   List<String> orderedPostProcessorNames = new ArrayList<>();
   3.4 Store the BeanName of the common BeanPostProcessor
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   // 4. Iterate through postProcessorNames
   for (String ppName : postProcessorNames) {
      // 4.1 Implement BeanPostProcessor processing for PriorityOrdered interfaces
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         / / 4.2 if pp corresponding Bean instance also implements the MergedBeanDefinitionPostProcessor interface, is added to the internalPostProcessors
         if (pp instanceofMergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); }}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         / / 4.3 implements Ordered interface, added to the orderedPostProcessorNames
         orderedPostProcessorNames.add(ppName);
      }
      else {
         / / 4.4 ordinary nonOrderedPostProcessorNamesnonOrderedPostProcessorNames.add(ppName); }}// First, register the BeanPostProcessors that implement PriorityOrdered.
   // 5. First, register BeanPostProcessors implementing the PriorityOrdered interface
   / / 5.1 sorting
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   / / 5.2 registerBeanPostProcessors registration
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
   // 6. Next, register BeanPostProcessors implementing Ordered interface
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String ppName : orderedPostProcessorNames) {
      // 6.1 Get the BeanPostProcessor corresponding to ppName
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      // add to orderedPostProcessors ready to perform registration
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         / / 6.3 if pp instance realized MergedBeanDefinitionPostProcessor interface, also added to the internalPostProcessorsinternalPostProcessors.add(pp); }}/ / 6.4 sorting
   sortPostProcessors(orderedPostProcessors, beanFactory);
   // add orderedPostProcessors
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // Now, register all regular BeanPostProcessors.
   // 7. Register normal 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.
   // finally, re-register internalPostProcessors, (equivalent to moving to the end of the list)
   / / 8.1 sorting
   sortPostProcessors(internalPostProcessors, beanFactory);
   // 8.2 Register internalPostProcessors
   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).
   / / 9. Register ApplicationListenerDetector, main purpose is to move to the end of the processing chain
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
Copy the code

priorityOrderedPostProcessors

I’m not going to talk about this one

registerBeanPostProcessors

/** * Register the given BeanPostProcessor beans. */
private static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, List
       
         postProcessors)
        {

   for(BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); }}Copy the code

beanFactory#addBeanPostProcessor

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
   Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
   // Remove from old position, if any
   // If it exists, remove it
   this.beanPostProcessors.remove(beanPostProcessor);
   // Track whether it is instantiation/destruction aware
   / / set the logo hasInstantiationAwareBeanPostProcessors
   if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
   }
   / / set the logo hasDestructionAwareBeanPostProcessors
   if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true;
   }
   // Add to end of list
   // Add beanPostProcessor to the list
   this.beanPostProcessors.add(beanPostProcessor);
}
Copy the code

To expand case

Define MyBeanPostProcessor to implement the BeanPostProcessor interface

public class MyBeanPostProcessor implements BeanPostProcessor.PriorityOrdered {

   @Override
   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      System.out.println("Before Bean instantiation... " + beanName);
      return bean;
   }

   @Override
   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      System.out.println("After Bean instantiation..." + beanName);
      return bean;
   }

   @Override
   public int getOrder(a) {
      return 0; }}Copy the code

Define the User object and define the Bean through Configuration

/ / the User object
public class User {
   private String name;

   public User(a) {
      System.out.println("User object instantiation");
   }

   public String getName(a) {
      return name;
   }

   public void setName(String name) {
      this.name = name; }}/ / define the Bean
@Configuration
public class BeanConfig {

   @Bean
   public User user(a) {
      return new User();
   }

   @Bean
   public MyPostProcessorBean myPostProcessorBean(a) {
      return newMyPostProcessorBean(); }}Copy the code

Unit testing

public class BeanPostProcessorTest {

   @Test
   public void test(a) {
      ApplicationContext context =
            newAnnotationConfigApplicationContext(BeanConfig.class); }}Copy the code

The results of

Watch out for two easy holes

  1. BeanPostProcessor depends on beans that do not execute BeanPostProcessor’s methods
  2. The BeanPostProcessor and its dependent beans cannot use AOP

The last

In this way, there are too many Spring concepts, so we need to sort out the differences between these points and draw more pictures.