spring官网笔记6

容器的扩展点(一)BeanFactoryPostProcessor

首先我们先看看官网怎么说的:

在这里插入图片描述

从上面这段话,我们可以总结如下几点:

1、BeanFactoryPostProcessor可以对Bean配置元数据进行操作,也就是说,S容器允许BeanFactoryPostProcessor读取指定Bean的配置元数据,并可以在Bean被实例化之前修改它,这里说的配置元数据其实就是我们讲过的Beandefinition.

2、我们可以配置多个BeanFactoryPostProcessor,并且我们只要配置的BeanFactoryPostProcessor实现了order接口的话,我们还可以控制这些BeanFactoryPostProcessor的执行顺序。

接下来我们通过demo来感受下BeanFactoryPostProcessor的作用:

例子:

这里就以官网上的demo为例:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
		<property name="locations" value="classpath:com/something/jdbc.properties"/>
	</bean>

	<bean id="dataSource" destroy-method="close"
		  class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${jdbc.driverClassName}"/>
		<property name="url" value="${jdbc.url}"/>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=root

在上面的例子中,我们配置了PropertySourcesPlaceholderConfigurer,为了方便理解,我们先分析下这个类,UML图如下

在这里插入图片描述

1、Ordered用于决定执行顺序

2、PriorityOrdered 这个接口直接集成Ordered接口,并没有做任务扩展,只是作为一个标记接口,也用于决定BeanFactoryPostProcessor的执行顺序,在后文源码中会看到它的作用

3、Aware相关的接口我们在介绍Bean的生命周期回调时统一分析,这里暂且不管

4、FunctionalInterface java8新增的一个接口,也只是起一个标记作用,标记该接口是一个函数接口

5、BeanFactoryPostProcessor 代表这个类是一个Bean工厂的后置处理器

6、PropertiesLoaderSupport 这个类定义了属性的加载方法,包含的属性如下

//本地属性可以直接在xml中配置
	@Nullable
	protected Properties[] localProperties;
	//是否用本地的属性覆盖提供的文件中的属性,默认不会
	protected boolean localOverride = false;
	//根据地址找到对应的文件
	@Nullable
	private Resource[] locations;
	//没有找到对应文件是否抛出异常false代表不抛出
	private boolean ignoreResourceNotFound = false;
	//对文件资源的编码
	@Nullable
	private String fileEncoding;
	//文件解析器
	private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();

PropertyResourceConfigurer这个类主要可以对读取到的属性进行一些转换

PlaceholderConfigurerSupport 主要负责对占位符进行解析,其中几个属性如下

	//默认解析的前缀
	public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";
	//默认解析的后缀
	public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
	//属性名称跟属性值的分隔符
	public static final String DEFAULT_VALUE_SEPARATOR = ":";

PropertySourcesPlaceholderConfigurer 继承了上面这些类的所有功能

对这个类有些了解后,我们回到前面的例子,为什么在jdbc.property文件的属性会被应用到BasicDataSource这个bean上呢?为了帮助大家理解,我画了一个图:

在这里插入图片描述

这个流程如上图我们可以看到通过PropertySourcesPlaceholderConfigurer 这个特殊的BeanFactoryProcessor完成了beanDefinition中的属性值中的占位符的替换,在BeanDefinition实例化之前就进行了更改

在上图中,创建Bean的过程我们暂且不管,还有一个问题我们需要弄清楚,Spring是如何扫描并解析成BeanDefinition的呢?这里就不得不提到我们接下来需要分析的这个接口BeanDefinitionRegistryPostProcessor。

BeanDefinitionRegistryPostProcessor(重要);

我们先看一下这个接口的UML类图

在这里插入图片描述

从上图中,我们可以得出两个结论:

1、BeanDefinitionRegistryPostProcessor直接继承了BeanFactoryPostProcessor,所以它也是一个Bean工厂的后置处理器

2、Spring 只提供了一个内置的BeanDefinitionRegistryPostProcessor的实现类ConfigurationClassPostProcessor,实际上上面说的扫描解析成Beandefinition的过程就是这个类完成的

我们看下这个接口定义:

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
@FunctionalInterface
public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}

相比于正常的BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor多提供了一个方法,那么多提供的这个方法有什么用呢?这个方法在什么时候执行呢?这里我先说结论。

这个方法就是为了扩展,执行时机比BeanFactoryPostProcessor的postProcessBeanFactory这个方法更加靠前,spring利用这个特性完成了BeanDefinition的扫描解析,我们对spring扩展时也可以用这个特性,比如最新的mybatis与spring整合就是利用了这个特性。这个后面再来分析

接下来,我们分析其源码,验证上面的结论。

执行流程源码解析:

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
这行代码的执行流程
// 1. 创建BeanFactory
// 2. 生成AnnotatedBeanDefinitionReader
// 3. 生成ClassPathBeanDefinitionScanner
this();
// 利用reader把componentClasses注册为一个BeanDefinition
register(componentClasses);
// 调用AbstractApplicationContext的refresh()方法,模板模式,会启动ApplicationContext
// 为什么叫refresh,而不叫start?
refresh();

BeanDefinitionRegistryPostProcessor的执行流程

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

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();
		//这个if基本上一定成立,除非我们手动new了一个BeanFactory
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			//存储了只实现了BeanFactoryPostProcessor接口的后置处理器
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			//存储了只实现了BeanDefinitionRegistryPostProcessor接口的后置处理器
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			// 这个beanFactoryPostProcessors集合一般情况下都是空的,除非我们手动调用容器的addBeanFactoryPostProcessor方法
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				// BeanDefinitionRegistryPostProcessor是一个特殊的BeanFactoryPostProcessor,需要先执行postProcessBeanDefinitionRegistry方法
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					//执行实现了BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					//保存只执行过了实现BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法的BeanDefinitionRegistryPostProcessor的接口
					registryProcessors.add(registryProcessor);
				}
				else {
					//保存了只实现了beanFactoryPostProcessor接口的后置处理器
					regularPostProcessors.add(postProcessor);
				}
			}

			// 保存当前需要执行的实现了BeanDefinitionRegistryPostProcessor接口的后置处理器
			// 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.
			// 首先,先执行实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				// 判断这个类是否还实现了PriorityOrdered接口
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// 这里调用了getBean,所以生成一个BeanDefinitionRegistryPostProcessor的bean对象
					//正常情况下只会有一个就是spring内置ConfigurationClassPostProcessor
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			//根据实现的PriorityOrdered进行排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			//将当前执行的currentRegistryProcessors全部添加到registryProcessors中
			registryProcessors.addAll(currentRegistryProcessors);
			// 执行postProcessBeanDefinitionRegistry方法 这个方法里面会进行BeanDefinition的扫描和解析
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			//清空集合
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			// 首先,先执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				//确保没有被处理过并且实现了order接口
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					//加入到当前需要执行的集合中
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			//根据order接口进行排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			//将需要执行的currentRegistryProcessors全部添加到registryProcessors集合里面
			registryProcessors.addAll(currentRegistryProcessors);
			//执行后置处理器的逻辑,这里只会执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry这个方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			//清空集合
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			// 最后,最后其他普通的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法
			boolean reiterate = true;
			// 在一个BeanDefinitionRegistryPostProcessor中可以注册另一个BeanDefinitionRegistryPostProcessor,所以需要递归找出所有的BeanDefinitionRegistryPostProcessor
			// 一个没有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor如果在内部注册了一个实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,那么就是没有实现PriorityOrdered接口的先执行
			while (reiterate) {
				reiterate = false;
				// 这里会再一次拿到实现了PriorityOrdered接口或Ordered接口的BeanDefinitionRegistryPostProcessor,所以需要processedBeans进行过滤
				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);
				currentRegistryProcessors.clear();
			}

			// =======BeanDefinition  解析配置类(扫描,- @Bean, @Import),手动,接口, @Import

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			// 执行完BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法后,
			// 再执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

			// 执行手动添加的非BeanDefinitionRegistryPostProcessor类型的Bean工厂后置处理器的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// 如果beanFactory没有可以注册BeanDefinition的功能,则没有BeanDefinitionRegistryPostProcessor,则执行Bean工厂后置处理器的postProcessBeanFactory方法
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// 总结一下上面的流程:
		// 1. 如果beanFactory实现了BeanDefinitionRegistry接口,则表示可以通过BeanDefinitionRegistryPostProcessor接口来注册BeanDefinition
		// 2. 因为现在是Spring启动过程中的比较早的阶段(还没有开始扫描@Component),所以只能获取Spring默认添加到BeanFactory中的bean工厂后置处理器,以及程序员手动添加的bean工厂后置处理器
		// 3. 执行的顺序是,先执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法,因为这个方法可以注册BeanDefinition
		// 4. 先执行手动添加进行来的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,这个过程中可能会向BeanFactory中注册其他的BeanDefinitionRegistryPostProcessor
		// 5. 从BeanFactory中获取PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,并执行postProcessBeanDefinitionRegistry方法
		// 6. 从BeanFactory中获取Ordered接口的BeanDefinitionRegistryPostProcessor,并执行postProcessBeanDefinitionRegistry方法
		// 7. 在5,6步中都有可能注册新的BeanDefinitionRegistryPostProcessor的
		// 8. 从BeanFactory中获取普通的BeanDefinitionRegistryPostProcessor,并执行postProcessBeanDefinitionRegistry方法
		// 9. 在8步中也有可能注册新的BeanDefinitionRegistryPostProcessor,所以第8步会递归,直到没有新的BeanDefinitionRegistryPostProcessor注册进来了
		// 10. 在前面的步骤中都是执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法,进行BeanDefinition的注册
		// 11. BeanDefinition注册完了之后,因为BeanDefinitionRegistryPostProcessor本身也是一个BeanFactoryProcessor,所以最后再执行postProcessBeanFactory方法
		// 12. 总结一句话就是:先通过BeanDefinitionRegistryPostProcessor注册BeanDefinition,再执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
		// 在默认情况下,上面的步骤中只有一个BeanDefinitionRegistryPostProcessor会执行,就是ConfigurationClassPostProcessor,因为它是Spring默认在添加进去的

		// BeanDefinitionRegistryPostProcessor是特殊的BeanFactoryPostProcessor,在上面的逻辑中都处理完了
		// 所以接下来就是处理普通的BeanFactoryPostProcessor
		// 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);
		// 默认情况下会拿到两个,一个就是ConfigurationClassPostProcessor,一个就是EventListenerMethodProcessor

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		// 保存直接实现了BeanFactoryPostProcessor接口和PriorityOrdered接口的后置处理器
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		// 保存直接实现了BeanFactoryPostProcessor接口和Ordered接口的后置处理器
		List<String> orderedPostProcessorNames = new ArrayList<>();
		// 保存直接实现了BeanFactoryPostProcessor接口的后置处理器,不包括那些实现了排序接口的类
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		// 把所有BeanFactoryPostProcessor进行分类
		for (String ppName : postProcessorNames) {
			// 拿到的BeanFactoryPostProcessor包括了BeanDefinitionRegistryPostProcessor,所以要跳过
			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.
		// 先执行实现了PriorityOrdered接口的BeanFactoryPostProcessor
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		// 再执行实现了Ordered接口的BeanFactoryPostProcessor
		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.
		// 最后执行普通的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// 到此,所有的BeanFactoryPostProcessor都执行完了
		// 对于BeanFactoryPostProcessor我们可以这么理解:它是去完善BeanFactory的,比如向BeanFactory中去注册BeanDefinition
		// 就好比:BeanFactory是一张白纸,每个BeanFactoryPostProcessor都去这张白纸上去画上一笔,这个白纸就丰满了

		// 所以这段代码,虽然内容很多,但是在默认情况下,主要就是执行了ConfigurationClassPostProcessor
		// 1. 先执行了ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,基本上就是去注册BeanDefinition
		// 2. 然后执行了ConfigurationClassPostProcessor的postProcessBeanFactory方法

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

另外在上面的代码中大家有没有发现一个问题,当在执行postProcessBeanDefinitionRegistry方法时采用了循环的方式,不断的查找BeanDefinitionRegistryPostProcessor,就是下面的代码

boolean reiterate = true;
			// 在一个BeanDefinitionRegistryPostProcessor中可以注册另一个BeanDefinitionRegistryPostProcessor,所以需要递归找出所有的BeanDefinitionRegistryPostProcessor
			// 一个没有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor如果在内部注册了一个实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,那么就是没有实现PriorityOrdered接口的先执行
			while (reiterate) {
				reiterate = false;
				// 这里会再一次拿到实现了PriorityOrdered接口或Ordered接口的BeanDefinitionRegistryPostProcessor,所以需要processedBeans进行过滤
				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);
				currentRegistryProcessors.clear();
			}

但是在执行postProcessBeanFactory并没有进行类似的查找。这是为什么呢?

笔者认为主要是设计使然,Spring在设计时postProcessBeanFactory这个方法不是用于重新注册一个Bean的,而是修改,我们可以看下这个方法可以看下这个方法的java doc

/**
	 * 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;

其中重要的一段话:All bean definitions will have been loaded,,所有的beanDefinition都已经被加载了

/**
	 * 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;

大家注意这段话 This allows for adding furtherbean definitions before the next post-processing phase kicks in.

我们允许我们在下个后置处理器执行前添加更多的beanDefinition.

从这里可以看出执行顺序来。

the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;


大家注意这段话  This allows for adding furtherbean definitions before the next post-processing phase kicks in.

我们允许我们在下个后置处理器执行前添加更多的beanDefinition.

从这里可以看出执行顺序来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值