Notas de lectura del código fuente de Spring (6) Interpretación de la línea principal registerBeanPostProcessors

Notas de lectura del código fuente de Spring (6)

Navegación anterior

Notas de lectura de fuentes de primavera (1)
Notas de lectura de fuentes de primavera (2)
Notas de lectura de fuentes de primavera (3)
Notas de lectura de fuentes de primavera (4)
Notas de lectura de fuentes de primavera (5)

Revisión anterior

imagen.png

En el artículo anterior, introduje el método prepareBeanFactory en la figura anterior. Vi que este método solo establece algunas variables miembro para la fábrica, como BeanpostProcessors, ignoreDependencyInterfaces y resolvableDependencies.

comienza oficialmente

postProcessBeanFactory

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
复制代码

Este método es relativamente simple, un método de plantilla, mire su clase anulada, ya sea que involucre a nuestra clase

imagen.pngComo se puede ver en la figura, todos están bajo el módulo spring-web, que no es el foco de nuestra atención aquí, sáltelo.

invocarBeanFactoryPostProcessors

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(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}
复制代码

El código anterior puede ver que el punto clave es.

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

Primero observe los dos parámetros de este método.

  1. beanFactory esto es fácil de explicar
  2. El segundo parámetro de getBeanFactoryPostProcessors() es un método, que literalmente significa obtener los postprocesadores de la fábrica Bean. Eche un vistazo a esta parte del código primero.
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
   return this.beanFactoryPostProcessors;
}
复制代码

Leer esto significa que hay una propiedad en applicationContext, que es el método get. A través de su método add, tengo la impresión de que no se ha ajustado ningún método en el método. Entonces la probabilidad obtenida es una Lista vacía.

imagen.png Debug一下确实是这么回事,这个方法的名字是invokeBeanFactoryPostProcessors,字面意思就是调用Bean工厂后处理器,这里因为我们没获取到,读也只能读哥寂寞,所以这个方法可以跳过。

registerBeanPostProcessors

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
复制代码

这里的代码只有一行,调用了一个方法registerBeanPostProcessors,这里看入参。

  1. beanFactory
  2. this

第一个值做什么用的,可以猜得到,注册就是注册到这个Bean工厂中。第二个参数传入了,当前的this就是applicationContext,因为PostProcessor也是Bean,所以这里猜想一下,是用来获取BeanDefinition的。接下来看一下这个方法的实现代码。

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.
   // 将实现 PriorityOrdered、Ordered 和其余部分的 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 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.
   // 首先,注册实现 PriorityOrdered 的 BeanPostProcessor。
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
   // 接下来,注册实现 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.
   // 现在,注册所有常规的 BeanPostProcessor。
   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.
   // 最后,重新注册所有内部 BeanPostProcessor。
   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).
   // 重新注册用于将内部 bean 检测为 ApplicationListeners 的后处理器,将其移动到处理器链的末尾(用于拾取代理等)。
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
复制代码

由于代码长度过长,阅读方法还是和之前的文章一样,采取分段的方式阅读。

第一段代码

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

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

由于之前在ObtainBeanFactory方法时,BeanFactory已经把Bean Definition加载进入了BeanFacotry中,所以在上述代码中,第一行获取了所有实现BeanPostProcessor接口的BeanName。

第二行中获取了申明了int的变量,他的组成是当前Bean工厂中的PostProcessor的数量 + 1 + 刚刚从工厂取到的自定义的PostProcess的数量。
这里为什么+1呢,在下一行代码有解释,因为他向BeanFactory中又追加了一个BeanPostProcessorChecker。

这个类是做什么的呢,根据字面意思和他的入参,我的理解是检查Bean什么的。这里后面有涉及的话,再过来看。

第二段代码

// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 将实现 PriorityOrdered、Ordered 和其余部分的 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 instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
      orderedPostProcessorNames.add(ppName);
   }
   else {
      nonOrderedPostProcessorNames.add(ppName);
   }
}
复制代码

这里相当于做了个分类汇总,把实现PriorityOrdered,Ordered的PostProcessor和其他的区分开来,分别放入不同的List当中去
关于这两个类,我想我就不用介绍了,就是用来Bean加载时排序使用的,应该都用过。
值得注意的是,这里除了PriorityOrdered储存的是实例,其他的都只存了Name,存储的并不是实例。

该方法中有一个getBean的方法,里面代码比较多,暂时就不关注他的细节了,后面单开一个章节讲解。

第三段代码

// First, register the BeanPostProcessors that implement PriorityOrdered.
// 首先,注册实现 PriorityOrdered 的 BeanPostProcessor。
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);


复制代码

两个方法比较简单,这里简单讲解一下,下面的代码中会有复用

sortPostProcessors 排序方法
// 排序方法
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);
}
复制代码

因为传进来的PostProcessor,都实现了Order接口,所以他们具备排序的能力,factory传进来的目的是为了判断,Factory是否有默认的排序器,如果没有的话,默认为排序方法传入Order的排序规则。

registerBeanPostProcessors 注册BeanPostProcessors
private static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> 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);
      }
   }
}
复制代码

这个方法较为简单,只是个简单的封装,防止外部写重复代码的。

第四段代码

// Next, register the BeanPostProcessors that implement Ordered.
// 接下来,注册实现 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);
复制代码

这个代码扫一眼就可以了,做的工作和他的注释说的是一样的。把实现order接口的注册到工厂中。最后两行代码和第三段代码的意思一样。

第五段代码

// Now, register all regular BeanPostProcessors.
// 现在,注册所有常规的 BeanPostProcessor。
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);
复制代码

这一段代码和上面一段代码类似,表达的一样的意思,唯一的区别就是,这里不需要把Bean排序了,因为这里注册的PostProcessor没有排序功能。

第六段代码

// Finally, re-register all internal BeanPostProcessors.
// 最后,重新注册所有内部 BeanPostProcessor。
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
复制代码

在前面的代码中,各位会发现for循环中,有个if,去判断是否MergedBeanDefinitionPostProcessor的,这里就是把那些PostProcessor,注册进容器,这里其实我有个疑惑,就是这个接口是干嘛,于是我好奇的点进去看了下他的实现,一看不得了。

imagen.png

这两个注解大家应该很熟悉,所以看来这个属性了不得,我们后面再来解析这个东西。

第七段代码

// Re-register post-processor for detecting inner beans as ApplicationListeners,
// 重新注册用于将内部 bean 检测为 ApplicationListeners 的后处理器,将其移动到处理器链的末尾(用于拾取代理等)。
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
复制代码

A decir verdad, no entiendo qué está haciendo esta clase ApplicationListenerDetector. Analicemos esta clase cuando leamos cuando se ejecuta.

llegado a su fin

Ver el método registerBeanPostProcessors hoy todavía es un poco simple, aquí hay solo un registro de algunos PostProcessors, y aún no se ha llegado al proceso de invocación.

Observaciones finales

El propósito de escribir artículos es ayudarlo a consolidar su conocimiento. Puede señalar cosas malas o incorrectas en el área de comentarios. Si lees el artículo y crees que te es útil puedes darle me gusta, si encuentras algunas preguntas que te generan dudas, o si no las entiendes puedes comentar, debes saberlo todo. Por supuesto, también espero hacerme amigo de todos y aprender unos de otros.

Supongo que te gusta

Origin juejin.im/post/7079818036730920974
Recomendado
Clasificación