【SpringCooking】厨师就位(四)refresh方法之 invokeBeanFactoryPostProcessors()

1. 背景介绍

在上一篇文章 【SpringCooking】厨师就位(三)refresh方法之prepareBeanFactory() 中,讲到了 prepareBeanFactory()是如何去准备 BeanFactory 的,此时厨师已经算是就位了,那么处理食材的刀具也需要准备好,厨师才能干活。

所以这篇文章就来重点分析 refresh() 中的 invokeBeanFactoryPostProcessors(),研究其是如何准备并执行 BeanFactoryPostProcessors 的。从下面代码可以看到,实际是委托给 PostProcessorRegistrationDelegate 来执行 BeanFactoryPostProcessors 的。在 Spring 的源码中,很多重要的类其实都是委托给其他类去干核心的事情,就像老板叫你干活。

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
		
	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()));
		}
	}
}

2. 学习目标

  1. 了解 BeanFactoryPostProcessor 的作用
  2. 了解 BeanFactoryPostProcessor 的执行顺序
  3. 了解 BeanDefinitionRegistryPostProcessor 的作用
  4. 清楚 Spring 内置的 BeanFactoryPostProcessor 何时执行

3. 关键问题

  1. ConfigurationClassPostProcessor 的执行时机
  2. 有办法让自定义的 BeanFactoryPostProcessors 先于 ConfigurationClassPostProcessor 执行吗

4. 源码追踪

在开始源码追前,我们有必要先了解 BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor这两个接口的功能。

笔者会贴上接口的注释,然后根据自己的理解,对一些重要的点进行翻译。也希望读者能养成看接口注释的习惯,这对阅读源码十分有帮助,能快速地让你了解这个接口的功能,同时也能让你清楚一些要注意的点

BeanFactoryPostProcessor

首先这是一个 Factory hook,所谓 hook 翻译过来是钩子,将其理解为一个扩展点即可。那这个钩子接口主要就用来自定义 BeanDefinition ,调整 bean 的 property value

适用于自定义配置文件覆盖已配置的 bean properties。如果有这种开箱即用的配置需求,具体可查看 PropertyResourceConfigurer 及其相关的实现

它不会与 bean 实例打交道,这样做会导致 bean 过早实例化,扰乱容器并造成一些不可预料的副作用。如果需要跟 bean 实例打交道,可以使用 BeanPostProcessor

ApplicationContext 会自动检测 BeanDefinition中的 BeanFactoryPostProcessor,在 bean 实例化之前执行它们。

BeanFactoryPostProcessor 可以通过 ConfigurableApplicationContext,以编码的方式进行注册。

笔者在看到这行注释的时候,便去找 ConfigurableApplicationContext 注册 BeanFactoryPostProcessor 的方法,结果真有一个方法是用来注册 BeanFactoryPostProcessor 的,这在笔者以前是不知道的

因此,对于【关键问题2】,我们可以通过 addBeanFactoryPostProcessor()来添加 BeanFactoryPostProcessor,事先执行自定义的 BeanFactoryPostProcessor

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
	void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);
}

ApplicationContext 会先检测实现了 PriorityOrdered 接口的 BeanFactoryPostProcessor ,然后再检测实现了 Ordered 接口的 BeanFactoryPostProcessor

而通过 ConfigurableApplicationContext 编码注册的 BeanFactoryPostProcessor,则是按照注册的顺序进行执行的,并不会理会是否实现了 PriorityOrdered 或 Ordered

此外,BeanFactoryPostProcessor 也不会考虑 @Order注解

Factory hook that allows for custom modification of an application context’s bean definitions, adapting the bean property values of the context’s underlying bean factory.

Useful for custom config files targeted at system administrators that override bean properties configured in the application context. See PropertyResourceConfigurer and its concrete implementations for out-of-the-box solutions that address such configuration needs.

A BeanFactoryPostProcessor may interact with and modify bean definitions, but never bean instances. Doing so may cause premature bean instantiation, violating the container and causing unintended side effects. If bean instance interaction is required, consider implementing BeanPostProcessor instead.

Registration
An ApplicationContext auto-detects BeanFactoryPostProcessor beans in its bean definitions and applies them before any other beans get created. A BeanFactoryPostProcessor may also be registered programmatically with a ConfigurableApplicationContext.

Ordering
BeanFactoryPostProcessor beans that are autodetected in an ApplicationContext will be ordered according to org.springframework.core.PriorityOrdered and org.springframework.core.Ordered semantics. In contrast, BeanFactoryPostProcessor beans that are registered programmatically with a ConfigurableApplicationContext will be applied in the order of registration; any ordering semantics expressed through implementing the PriorityOrdered or Ordered interface will be ignored for programmatically registered post-processors. Furthermore, the @Order annotation is not taken into account for BeanFactoryPostProcessor beans.

综上,BeanFactoryPostProcessor 有以下特点:

  1. 与 BaenDefinition 交互
  2. 可通过 ConfigurableApplicationContext 手动注册,并且执行的顺序与注册的顺序一致
  3. ApplicationContext 自动检测实现了 PriorityOrdered 和 Ordered 的BeanFactoryPostProcessor ,并按照 PriorityOrdered 和 Ordered 的顺序执行 BeanFactoryPostProcessor
  4. @Order 注解在 BeanFactoryPostProcessor 的执行顺序上不起效
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

BeanDefinitionRegistryPostProcessor

BeanFactoryPostProcessor 的拓展,允许在 BeanFactoryPostProcessor 执行前注册更多的 BeanDefinition

特别要注意的是,它注册的 BeanDefinition 可以是 BeanFactoryPostProcessor

这一点在后续分析 ConfigurationClassPostProcessor 解析配置类的时候就能体现,当我们自定义了 BeanDefinitionRegistryPostProcessor 或者 BeanFactoryPostProcessor ,ConfigurationClassPostProcessor 就会帮我们注册其 BeanDefinition

Extension to the standard BeanFactoryPostProcessor SPI, allowing for the registration of further bean definitions before regular BeanFactoryPostProcessor detection kicks in. In particular, BeanDefinitionRegistryPostProcessor may register further bean definitions which in turn define BeanFactoryPostProcessor instances.

可以看出 BeanFactoryPostProcessor 与 BeanDefinitionRegistryPostProcessor 的区别在于,前者是修改 BeanDefinition,后者是注册 BeanDefinition

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean definition registry after its
	 * standard initialization. All regular bean definitions will have been loaded,
	 * but no beans will have been instantiated yet. This allows for adding further
	 * bean definitions before the next post-processing phase kicks in.
	 * @param registry the bean definition registry used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

Ordered

优先级越高,值越小

Ordered is an interface that can be implemented by objects that should be orderable, for example in a Collection.

The actual order can be interpreted as prioritization, with the first object (with the lowest order value) having the highest priority.

Note that there is also a priority marker for this interface: PriorityOrdered. Consult the Javadoc for PriorityOrdered for details on how PriorityOrdered objects are ordered relative to plain Ordered objects.

Consult the Javadoc for OrderComparator for details on the sort semantics for non-ordered objects.

public interface Ordered {

	/**
	 * Useful constant for the highest precedence value.
	 * @see java.lang.Integer#MIN_VALUE
	 */
	int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;

	/**
	 * Useful constant for the lowest precedence value.
	 * @see java.lang.Integer#MAX_VALUE
	 */
	int LOWEST_PRECEDENCE = Integer.MAX_VALUE;


	/**
	 * Get the order value of this object.
	 * <p>Higher values are interpreted as lower priority. As a consequence,
	 * the object with the lowest value has the highest priority (somewhat
	 * analogous to Servlet {@code load-on-startup} values).
	 * <p>Same order values will result in arbitrary sort positions for the
	 * affected objects.
	 * @return the order value
	 * @see #HIGHEST_PRECEDENCE
	 * @see #LOWEST_PRECEDENCE
	 */
	int getOrder();

}

PriorityOrdered

Ordered 的拓展接口,优先级优于 Ordered 接口

Extension of the Ordered interface, expressing a priority ordering: PriorityOrdered objects are always applied before plain Ordered objects regardless of their order values.

When sorting a set of Ordered objects, PriorityOrdered objects and plain Ordered objects are effectively treated as two separate subsets, with the set of PriorityOrdered objects preceding the set of plain Ordered objects and with relative ordering applied within those subsets.

This is primarily a special-purpose interface, used within the framework itself for objects where it is particularly important to recognize prioritized objects first, potentially without even obtaining the remaining objects. A typical example: prioritized post-processors in a Spring org.springframework.context.ApplicationContext.

Note: PriorityOrdered post-processor beans are initialized in a special phase, ahead of other post-processor beans. This subtly affects their autowiring behavior: they will only be autowired against beans which do not require eager initialization for type matching.

public interface PriorityOrdered extends Ordered {
}

PostProcessorRegistrationDelegate

  1. 先执行 BeanDefinitionRegistryPostProcessor

    先执行 BeanDefinitionRegistryPostProcessor 接口本身的方法 postProcessBeanDefinitionRegistry()
    再执行继承了 BeanFactoryPostProcessor 的 postProcessBeanFactory()

  2. 后执行 BeanFactoryPostProcessor

每个执行操作其实还可以细分成以下步骤:

  1. 检测 - 从 bean definition 和 manually register singletons 查找
  2. 过滤 - 筛选出实现了 PriorityOrdered 或 Ordered 的接口
  3. 实例化 - 通过 beanFactory.getBean()实例化
  4. 排序 - 对 BeanFactoryPostProcessor 进行排序
  5. 执行 - 按照排好的顺序执行

我们查看目前 BeanFactory 存在哪些 BeanDefinitionRegistryPostProcessor 或 BeanFactoryPostProcessor 的 BeanDefinition 或者 Singleton 了

beanNamebeanClassInterface
org.springframework.context.annotation.internalConfigurationAnnotationProcessorConfigurationClassPostProcessorBeanDefinitionRegistryPostProcessor
org.springframework.context.event.internalEventListenerFactoryDefaultEventListenerFactoryEventListenerFactory
org.springframework.context.event.internalEventListenerProcessorEventListenerMethodProcessorBeanFactoryPostProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessorAutowiredAnnotationBeanPostProcessorBeanPostProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessorCommonAnnotationBeanPostProcessorBeanPostProcessor
conditionalConfigConditionalConfig配置类

这些 BeanDefinition 是在 new AnnotatedBeanDefinitionReader() 注册进来的,具体可参考 【Spring cooking】厨师就位(一)AnnotationConfigApplicationContext

可以看到,在执行 invokeBeanFactoryPostProcessors()之前,其实已经有两个 BeanFactoryPostProcessor 的 BeanDefinition 注册进来了,分别是 ConfigurationClassPostProcessorEventListenerMethodProcessor。因此这两个 BeanFactoryPostProcessor 会被检测并执行

其中 ConfigurationClassPostProcessor 极为重要,用于解析我们的配置类,注册相关组件的 BeanDefinition

执行 BeanDefinitionRegistryPostProcessor

  1. 执行通过ConfigurableApplicationContext.addBeanFactoryPostProcessor()手动注册的 BeanDefinitionRegistryPostProcessor

  2. 检测并执行实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor

  3. 检测并执行实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor

  4. 检测并执行剩下的 BeanDefinitionRegistryPostProcessor

  5. 执行所有 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory()

执行 BeanFactoryPostProcessor

  1. 按照 PriorityOrdered,Ordered,nonOrdered 对 BeanFactoryPostProcessor 分类

    PriorityOrdered 的 BeanFactoryPostProcessor 先实例化再添加到集合
    Ordered/nonOrdered 的 BeanFactoryPostProcessor 直接将名字添加到集合

  2. PriorityOrdered 的 BeanFactoryPostProcessor 排序并执行

  3. 实例化 Ordered 的 BeanFactoryPostProcessor ,然后再排序并执行

  4. 实例化 nonOrdered 的 BeanFactoryPostProcessor , 然后再排序并执行

final class PostProcessorRegistrationDelegate {
	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 查找类型为 BeanDefinitionRegistryPostProcessor 的 beanName。这是 ListableBeanFactory 的方法
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				// 过滤出实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// 通过 beanFactory.getBean 实例化 BeanDefinitionRegistryPostProcessor ,并添加到集合中去
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			// 对 BeanDefinitionRegistryPostProcessor 集合排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			// 执行 BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			// 因为在执行 BeanDefinitionRegistryPostProcessor 的时候,有可能注册了新的 BeanDefinitionRegistryPostProcessor
			// 需要调用 getBeanNamesForType 重新检测一遍
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}
}

5. 结论

  1. 了解 BeanFactoryPostProcessor 的作用

    BeanFactoryPostProcessor 直译就是 BeanFactory 后置处理器,它是在 prepareBeanFactory 之后去执行的,主要作用就是自定义 BeanDefinition

  2. 了解 BeanFactoryPostProcessors 的执行顺序

    按照 PriorityOrdered,Ordered,nonOrdered 的顺序执行

  3. 了解 BeanDefinitionRegistryPostProcessor 的作用

    BeanFactoryPostProcessor 的拓展接口,主要作用就是注册 BeanDefinition

  4. 清楚 Spring 内置的 BeanFactoryPostProcessor 何时执行

    Spring 内置了两个 BeanFactoryPostProcessor

     ConfigurationClassPostProcessor - BeanDefinitionRegistryPostProcessor - PriorityOrdered
     EventListenerMethodProcessor - BeanFactoryPostProcessor
    

    ConfigurationClassPostProcessor 实现了 PriorityOrdered 接口,执行时机仅次于手动注册 BeanDefinitionRegistryPostProcessor

6. 注意细节

  1. 对于 BeanDefinitionRegistryPostProcessor 的执行

    ConfigurationClassPostProcessor 在前面 AnnotatedBeanDefinitionReader 初始化的时候,通过 AnnotationConfigUtils.registerAnnotationConfigProcessors 注册过BeanDefinition

    在 BeanDefinitionRegistryPostProcessor 执行的过程中,可能会注册其他的 BeanDefinitionRegistryPostProcessor 的 BeanDefiniton。

    如 ConfigurationClassPostProcessor 解析配置类,可以解析到我们自定义的 BeanDefinitionRegistryPostProcessor 并注册其 BeanDefinition。

    所以它并不像执行BeanFactoryPostProcessor那样,一次性获取所有的BeanFactoryPostProcessor然后分类、排序、执行。

    在每次执行某类 BeanDefinitionRegistryPostProcessor 前,都会重新调用BeanFactory.getBeanNamesForType() 来获取最新的结果

7. 待研究

  1. beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)
    此方法是如何去查找特定类型的 beanName 的

  2. 存放 BeanFactoryPostProcessor 的集合并不全是 List<BeanFactoryPostProcessor>

    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    

    在执行 BeanPostProcessor 时,priorityOrderedPostProcessors 集合类型为 List<BeanFactoryPostProcessor>,其他两种则为 List<String>,为什么不把其他两种也声明为 List<BeanFactoryPostProcessor>。在后续注册 BeanPostProcessor 时也是如此。

  3. sortPostProcessors(currentRegistryProcessors, beanFactory)
    同类的 BeanFactoryPostProcessor 之间是如何排序的

8. 推荐文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值