Bootstrap

springboot ApplicationContext之invokeBeanFactoryPostProcessors

在之前的springboot 启动bean加载处理器ConfigurationClassPostProcessor系列文章中,只是介绍了它的作用。那么这里有以下几个问题:

  1. ConfigurationClassPostProcessor 什么时候加载到spring容器中?
  2. ConfigurationClassPostProcessor 是什么时候起作用的?
  3. 为什么会先执行postProcessBeanDefinitionRegistry方法,然后再执行postProcessBeanFactory的呢?

springboot在启动准备好环境environment《springboot启动之配置文件秘密》,会进入ApplicationContext相关流程

public class SpringApplication {
	...
	public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			//进入ApplicationContext相关流程,首先是创建
			context = createApplicationContext();
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

	public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
			+ "annotation.AnnotationConfigApplicationContext";

	/**
	 * The class name of application context that will be used by default for web
	 * environments.
	 */
	public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
			+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";

	/**
	 * The class name of application context that will be used by default for reactive web
	 * environments.
	 */
	public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
			+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";
	//创建 ApplicationContext,
	protected ConfigurableApplicationContext createApplicationContext() {
		Class<?> contextClass = this.applicationContextClass;
		if (contextClass == null) {
			try {
				switch (this.webApplicationType) {
				case SERVLET:
					contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
					break;
				case REACTIVE:
					contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
					break;
				default:
					contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
				}
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
			}
		}
		return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
	}
}

不管那种类型,在其构造方法中都会创建一个

this.reader = new AnnotatedBeanDefinitionReader(this);

在AnnotatedBeanDefinitionReader构造方法中

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
	this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	Assert.notNull(environment, "Environment must not be null");
	this.registry = registry;
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

会调用AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)方法进行注入AnnotationConfigProcessors

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

这个时候容器中就会存在两个重要的bean,这也就解释了开头的第一个问题

那么第二个问题,是什么时候起作用的?springboot再创建好ApplicationContext,并执行prepareContext方法后,会执行refreshContext,就来到了今天的主角invokeBeanFactoryPostProcessors,这个方法比较长,主要分成两个流程

  1. 处理BeanDefinitionRegistryPostProcessor实现类
  2. 处理BeanFactoryPostProcessor实现类
    这里要注意BeanDefinitionRegistryPostProcessor 本来就是继承了 BeanFactoryPostProcessor。
    先不管逻辑是怎么实现的,开头的第二(是什么时候起作用的)、三(为什么会先执行postProcessBeanDefinitionRegistry方法,然后再执行postProcessBeanFactory的呢)个问题想必已经清楚了。

不能耍流氓是吧,总得出的干货,来先看处理BeanDefinitionRegistryPostProcessor流程

在这里插入图片描述
依次对箭头中的方块流程解释下:

  • 紫色,invokeBeanFactoryPostProcessors方法的有会获取当前ApplicationContext中的beanFactoryPostProcessors
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

它是在创建好ApplicationContext后执行prepareContext的方法的applyInitializers加入,会执行ApplicationContextInitializer(创建SpringApplication 时候从spring.factories加载,要加载自定义的BeanDefinitionRegistryPostProcessor ,这是个入口)类型的,这里就不展开默认三个类型作用了

  • 橙色,这是个重要步骤,执行前会去当前的容器中获取类型为:BeanDefinitionRegistryPostProcessor,当然会获取到ConfigurationClassPostProcessor,在执行postProcessBeanDefinitionRegistry(这里的前提是实现了接口PriorityOrdered),之前分析这个步骤的作用(加载更多的类到容器中)
  • 粉色,执行前会去容器中再去取BeanDefinitionRegistryPostProcessor,我们自定义并且实现该接口的就会在这里执行,然后执行实现接口Ordered,区分优先级,注意这里PriorityOrdered优先级已经失效了,因为在上一步已经执行过了,要想实现PriorityOrdered接口功能,可以在紫色步骤。
  • 蓝色,执行未实现PriorityOrdered、Ordered,并执行postProcessBeanDefinitionRegistry,这里是个while循环
  • 绿色,执行方法postProcessBeanFactory,这里的类型当然是BeanDefinitionRegistryPostProcessor

再继续看下是怎么处理BeanFactoryPostProcessor的?
在这里插入图片描述
这个流程相对比较简单,从当前的容器中获取BeanFactoryPostProcessor,过滤掉在上一步已经处理的bean,然后按照PriorityOrdered、Ordered、none进行分组并排序,依次执行priorityOrderedPostProcessors、orderedPostProcessorNames、nonOrderedPostProcessorNames组中的postProcessBeanFactory方法。

总结下:BeanDefinitionRegisterPostProcess、BeanFactoryPostProcess作用,BeanDefinitionRegisterPostProcess可以作为向容器中加载bean处理,例如ConfigurationClassPostProcessor ,BeanFactoryPostProcess可以作为修改加载bean定义属性!

实际操作验证下,我们定义一下几种bean

@Component
public class BeanDefinitionRegisterPostProcessNormal implements BeanDefinitionRegistryPostProcessor{}

@Component
public class BeanDefinitionRegisterPostProcessWithOrdered implements BeanDefinitionRegistryPostProcessor, PriorityOrdered{}

@Component
public class BeanDefinitionRegisterPostProcessWithPriorityOrdered implements BeanDefinitionRegistryPostProcessor, PriorityOrdered{}

@Component
public class BeanFactoryPostProcessWithOrder implements BeanFactoryPostProcessor, Ordered{}

@Component
public class BeanFactoryPostProcessWithPriorityOrder implements BeanFactoryPostProcessor, PriorityOrdered {}

依次输出为:

BeanDefinitionRegisterPostProcessWithOrdered -->postProcessBeanDefinitionRegistry
// 看这个PriorityOrdered优势没了
BeanDefinitionRegisterPostProcessWithPriorityOrdered -->postProcessBeanDefinitionRegistry
BeanDefinitionRegisterPostProcessNormal -->postProcessBeanDefinitionRegistry
BeanDefinitionRegisterPostProcessWithOrdered -->postProcessBeanFactory
BeanDefinitionRegisterPostProcessWithPriorityOrdered -->postProcessBeanFactory
BeanDefinitionRegisterPostProcessNormal -->postProcessBeanFactory
BeanFactoryPostProcessWithPriorityOrder-->postProcessBeanFactory
BeanFactoryPostProcessWithOrder-->postProcessBeanFactory
//这个是自定义实现BeanFactoryPostProcessor,未实现PriorityOrdered、Ordered
UpdateDataSourcePrefix-->postProcessBeanFactory

符合我们分析的逻辑
;