Spring source code

Before the report navigation

Spring Source reading notes (1) Spring source reading notes (2) Spring source reading notes (3) Spring source reading notes (4) Spring source reading notes (5)

Before the review

In the previous article, has introduced to the prepareBeanFactory method in the figure above, see this method just set up some member variables for the factory, for example, BeanpostProcessors ignoredDependencyInterfaces, ResolvableDependencies.

The official start of the

postProcessBeanFactory

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {}Copy the code

This is a simple method, a template method, and let’s see if its overriding class, does it involve our class

As you can see, these are all under the Spring-Web module. This is not our focus, so skip it.

invokeBeanFactoryPostProcessors

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if(! NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() ==null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }}Copy the code

As you can see from the code above, the key is this.

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

First take a look at the method’s two inputs.

  1. BeanFactory is easy to explain
  2. GetBeanFactoryPostProcessors () the second parameter is a method, literally get Bean post processor of the factory. So let’s look at this part of the code.
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors(a) {
   return this.beanFactoryPostProcessors;
}
Copy the code

Reading this means that there is a property in the applicationContext, and that is the get method. Through his add method, I don’t remember any method in the method. So the probability of getting it is a List of empty.

The Debug is indeed the way it is, the name of this method is invokeBeanFactoryPostProcessors, literally, call the Bean factory after processor, here because we didn’t get to, read only elder brother of lonely, so this method can be skipped.

registerBeanPostProcessors

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
Copy the code

Here is only one line of code, calling a method registerBeanPostProcessors, here to see into the refs.

  1. beanFactory
  2. this

What the first value does, as you can guess, is register into the Bean factory. The second argument is passed in. The current this is the applicationContext, and since the PostProcessor is also a Bean, it’s supposed to get the BeanDefinition. Let’s look at the implementation code for this method.

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

   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true.false);

   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   // Separate the implementation of PriorityOrdered, Ordered and the rest of the BeanPostProcessor.
   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 instanceofMergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); }}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else{ nonOrderedPostProcessorNames.add(ppName); }}// First, register the BeanPostProcessors that implement PriorityOrdered.
   // First, register the BeanPostProcessor that implements PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
   // Next, register the Ordered BeanPostProcessor.
   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.
   // 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.
   // 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).
   // Re-register the post-process used to detect the internal beans as ApplicationListeners, moving them to the end of the processor chain (for pickup agents, etc.).
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
Copy the code

Because the code length is too long, the method of reading is the same as the previous article, adopt a segmented reading method.

First code

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true.false);

int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
Copy the code

Since BeanFactory already loaded the Bean Definition into BeanFacotry when using the ObtainBeanFactory method, in the above code, The first line gets all the Beannames that implement the BeanPostProcessor interface.

The second line gets the variable declared int, which consists of the number of PostProcessors in the current Bean factory + 1 + the number of custom PostProcesses just fetched from the factory. Why +1 here is explained in the next line of code, because it appends a BeanPostProcessorChecker to the BeanFactory.

What does this class do, according to its literal meaning and its input parameter, is check beans and so on. If there’s anything involved later here, come back.

Second code

// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// Separate the implementation of PriorityOrdered, Ordered and the rest of the BeanPostProcessor.
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 instanceofMergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); }}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
      orderedPostProcessorNames.add(ppName);
   }
   else{ nonOrderedPostProcessorNames.add(ppName); }}Copy the code

So this is sort of a sort of summary, sort of a classification of postprocessors that implement PriorityOrdered, Ordered things, and put them in separate lists of classes that I don’t think I need to go through, that are used to sort beans when they load, they’ve all been used. Note that PriorityOrdered stores only the Name, not the instance.

There is a getBean method in this method, which has more code, so I will not pay attention to his details for the moment, and I will open a chapter to explain it later.

The third code

// First, register the BeanPostProcessors that implement PriorityOrdered.
// First, register the BeanPostProcessor that implements PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);


Copy the code

The two methods are relatively simple, which are explained briefly here, and will be reused in the following code

Sorting methods sortPostProcessors
// Sort methods
private static void sortPostProcessors(List
        postProcessors, ConfigurableListableBeanFactory beanFactory) {
   // Nothing to sort?
   if (postProcessors.size() <= 1) {
      return;
   }
   Comparator<Object> comparatorToUse = null;
   if (beanFactory instanceof DefaultListableBeanFactory) {
      comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
   }
   if (comparatorToUse == null) {
      comparatorToUse = OrderComparator.INSTANCE;
   }
   postProcessors.sort(comparatorToUse);
}
Copy the code

Since the PostProcessor passed in implements the Order interface, they have the ability to sort. The purpose of factory passing in is to determine whether factory has a default collator. If not, it will pass the Order collation rules for sorting methods by default.

RegisterBeanPostProcessors registered BeanPostProcessors
private static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, List
       
         postProcessors)
        {

   if (beanFactory instanceof AbstractBeanFactory) {
      // Bulk addition is more efficient against our CopyOnWriteArrayList there
      ((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
   }
   else {
      for(BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); }}}Copy the code

This method is relatively simple, just a simple encapsulation, prevent external write duplicate code.

The fourth code

// Next, register the BeanPostProcessors that implement Ordered.
// Next, register the Ordered BeanPostProcessor.
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);
Copy the code

This code, at a glance, does what his comments say it does. Register the factory that implements the ORDER interface. The last two lines of code mean the same as the third.

The fifth code

// Now, register all regular BeanPostProcessors.
// 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);
Copy the code

This code is similar to the previous one, but the only difference is that there is no need to sort the beans, because the PostProcessor registered here does not have sorting capabilities.

Code 6

// Finally, re-register all internal BeanPostProcessors.
// Finally, re-register all internal BeanpostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
Copy the code

In the previous code, you will find in the for loop, there is a if, to judge whether MergedBeanDefinitionPostProcessor, here is the PostProcessor, register into the container, here I have a doubt, this is the interface is why, So I was curious to go in to see his implementation, a look.

These two annotations should be familiar to you, so this looks like a pretty cool property, and we’re going to parse this thing later.

Section 7 code

// Re-register post-processor for detecting inner beans as ApplicationListeners, // Re-register the post-process used to detect the internal beans as ApplicationListeners, moving them to the end of the processor chain (for pickup agents, etc.). // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));Copy the code

Was really the ApplicationListenerDetector class I didn’t understand is why now, read when he run behind us to resolve this class.

Come to an end

See registerBeanPostProcessors method, today I still have a simple, here are just some PostProcessor for registration, also not to invoke the process.

conclusion

The purpose of writing an article is to help you consolidate your knowledge. You can point out your bad or wrong writing in the comments section. If you read the article and think it is helpful to you, you can like it. If you find some questions and have doubts, or do not understand, you can comment. Of course, I also hope to make friends with you and learn from each other.