invokeBeanFactoryPostProcessors

refresh里面的invokeBeanFactoryPostProcessors方法。

这个方法干了什么呢?,执行所有实现了 BeanDefinitionRegistryPostProcessor接口的bd ,会执行所有实现了 BeanFactoryPostProcessor接口的bd。

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;

}
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;

}

可以看看这两个接口,方法,参数。

ConfigurableListableBeanFactory 的一些方法之前也有讲过就不讲了

看看BeanDefinitionRegistry 能干什么,

public interface BeanDefinitionRegistry extends AliasRegistry {

	/**
	 * 在此注册表中注册一个新的bean定义。必须支持RootBeanDefinition和ChildBeanDefinition。
	 * @param beanName 要注册的bean实例的名称
	 * @param beanDefinition 要注册的bean实例的定义
	 *指定的bean名称,我们不允许覆盖它
	 * @see GenericBeanDefinition
	 * @see RootBeanDefinition
	 * @see ChildBeanDefinition
	 */
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException;

	/**
	 * Remove the BeanDefinition for the given name.
	 * @param beanName the name of the bean instance to register
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 */
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * Return the BeanDefinition for the given bean name.
	 * @param beanName name of the bean to find a definition for
	 * @return the BeanDefinition for the given name (never {@code null})
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 */
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * Check if this registry contains a bean definition with the given name.
	 * @param beanName the name of the bean to look for
	 * @return if this registry contains a bean definition with the given name
	 */
	boolean containsBeanDefinition(String beanName);

	/**
	 * Return the names of all beans defined in this registry.
	 * @return the names of all beans defined in this registry,
	 * or an empty array if none defined
	 */
	String[] getBeanDefinitionNames();

只截了一部分,可以看到BeanDefinitionRegistry主要是对bd的操作。先有这个认知再看这个方法的源码

 

 

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		//1.beanFactory --获取beanFactory当中的BeanFactoryPostProcessor
		//2.List<BeanFactoryPostProcessor> beanFactoryPostProcessors 存的是程序员手动通过api往spring容器当中提供得BeanFactoryPostProcessor
		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 (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

看注释

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


		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		//所有已经找出来的(已经处理了,已经执行完的) BeanFactoryPostProcessor 或者 BeanDefinitionRegistryPostProcessor
		//仅仅存放名字,保证不会重复执行
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {

			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			//存放所有找出来的 BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			//存放所有找出来的 BeanDefinitionRegistryPostProcessor
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			//遍历beanFactoryPostProcessors 方法传进来的一个list集合
			//spring最先执行得是程序员通过api提供得 context.addBeanFactoryPostProcessor(new bfpp)
			//因为这时候还没有扫描,就直接加进去了
			//为什么最先执行他?为什么和扫描得执行时机不一样呢?
			//一般没有元素
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				//如果有的情况下首先 判断是否子类
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					//如果是强转后直接执行
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					//执行完成后存放registryProcessors
					//为什么执行完成了之后还要存放到这个list当中呢?
					//主要是因为这里是判断子类,虽然子类的回调方法执行完成了
					//但是父类的回调方法没有执行,存放到这个list当中就是为了
					//后续到了执行父类回调的时机得时候,去遍历这个list,然后依次获取出来执行
					registryProcessors.add(registryProcessor);
				}
				else {
					//如果是父类的先不执行,先把他add到这个list当中
					//意义和上面一样,主要是为了时机到了时候遍历然后执行
					//既然这两个list仅仅是存放后在获取为什么需要两个呢?
					//其实一个就能解决
					//我的理解两个原因
					//1、毕竟这是两种类一种子类一种父类,分开存放更加的合理
					//2、也是最重要的原因,spring还是得区分这两种类的父类方法得执行顺序
					//虽然都是执行父类的回调,但是直接实现父类的类和直接实现子类的类如果分开存放
					//则可以控制这两类类的执行顺序和时机  当然这只是我的理解---不知道能不能说服你
					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.
			//定义了一个集合来存放当前需要执行的 BeanDefinitionRegistryPostProcessor 为什么需要这个集合
			//因为在spring的代码角度考虑BeanDefinitionRegistryPostProcessor的种类很多
			//主要三种
			//1、实现了 PriorityOrdered接口类型的
			//2、实现了 Ordered 接口类型的
			//3、什么都没实现
			//站在BeanDefinitionRegistryPostProcessor的来源角度来考虑分为两种
			//1、spring自己提供的
			//2、外部提供的
			//3、api提供得
			//由于 BeanDefinitionRegistryPostProcessor种类很复杂,故而spring得分批执行
			//这样能保证这些不同类型得BeanDefinitionRegistryPostProcessor 得执行时机
			//所以每次找到合适得,就需要一个集合来存放,然后执行
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			/**
			 *需要执行BeanDefinitionRegistryPostProcessor 首先得实例化
			 *实例化之前首先spring得知道整个容器当中有哪些BeanDefinitionRegistryPostProcessor
			 * 容器里面有几个BeanDefinitionRegistryPostProcessor
			 *  执行内部的BeanDefinitionRegistryPostProcessor
			 *  ConfigrationClassPostPorcessor#postProcessBeanDefinitionRegistry  扫描
			 *  实例化这个类
			 */
			//首先从容器(单例池或者bdmap)当中找到所有实现了 BeanDefinitionRegistryPostProcessor接口得类得名字
			//从这里可知由于整个spring容器还在启动得过程中,所以这里能找到得就是spring内置得一些BeanDefinitionRegistryPostProcessor
			//正常情况下 执行玩这里 这个 postProcessorNames得长度=1
			//因为这里可以找到一个 属于BeanDefinitionRegistryPostProcessor类型的bd
			//spring在启动的时候自己往bdMap当中添加的那个 ConfigrationClassPostPorcessor
			// First, invoke the BeanDefinitionRegistryPostProcessors .
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

			//根据名字去得到这个bean(实例化)
			for (String ppName : postProcessorNames) {
				//有没有实现PriorityOrdered接口
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					//有则取,无则实例化然后put到单例池 然后在返回
					//得到bean之后放到当前需要执行得list当中
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					//add完成之后表示spring接下来一定会去执行他
					//表示这个bean已经处理过了,下次在找到也不会添加到当前list当中
					processedBeans.add(ppName);
				}
			}

			//排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			//为什么需要addAll
			//添加到 registryProcessors 方便执行父类得回调
			registryProcessors.addAll(currentRegistryProcessors);
			//因为这个currentRegistryProcessors当中正常情况里面只有一个bean ConfigrationClassPostPorcessor
			//所以这个方法的意义就是执行 ConfigrationClassPostPorcessor#postProcessBeanDefinitionRegistry
			//这个方法做了很多事情
			//1、完成了扫描
			//完成了扫描  postProcessor.postProcessBeanDefinitionRegistry 注册bd
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

			//因为已经执行完了,故而需要清除这个当前list
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			// getBeanNamesForType  -----bean的名字
			//然后再从容器当中找BeanDefinitionRegistryPostProcessor
			//为什么还要找?前面不是找过了?
			//原因有两个
			//1、BeanDefinitionRegistryPostProcessor得主要功能就是往容器注册bd
			//由于前面执行过一次,你不能保证他没有向容器当中注册一些bd,故而有可能前面那次执行
			//就往容器里面注册了新的 BeanDefinitionRegistryPostProcessor 得bd 所以这里需要再找一此
			//2、正如1所说得,其实第一次执行 BeanDefinitionRegistryPostProcessor 就是完成扫描
			//所以有可能扫描到了程序员提供得 BeanDefinitionRegistryPostProcessor
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				//找到之后首先判断是否被处理过,因为这里肯定也能找i出来第一次已经执行过的哪些 BeanDefinitionRegistryPostProcessor
				//由于已经执行过的存在processedBeans这个集合,故而这里不会进if,也就是已经执行过的不会存在当前list
				//然后再去判断是否 实现了Ordered接口
				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);

			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			//这里为是什么需要进行一个while得循环?

			//执行所有没有实现PriorityOrdered 没有Ordered的BeanDefinitionRegistryPostProcessor的bean
			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);
						//如果能够找到一个说明可能会往容器当中添加新的bd
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			//到此为止 spring已经把容器所有得实现了 BeanDefinitionRegistryPostProcessor接口得
			// 回调全部执行完了  接下来需要执行父类得
			//由于前面执行得全部是子类所以必然也全部是父类
			//所以前面所有执行得子类都需要再执行一边父类
			//于是从registryProcessors(已经全部执行完子类回调得哪些类)遍历出来执行父类得回调

			//这里执行父类的回调,但是先是执行实现了子类的bean的父类回调
			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);


			//执行直接实现了父类的回调  context.addBeanFactoryPostProcessor("父类");
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

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

		/**
		 * 执行父类得回调(直接实现了父类得)  扫描得到得类
		 *
		 * beanFactory是无法注册bd进容器里的,所以不用向上面子类一样。他们所想要得到的效果是一样的,但是过程操作不同
		 */

		// 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...
		//清除 mergedMap 清除allBeanNamesByType 缓存
		//这里清除缓存主要是为了合并 --
		// 因为到此为止,spring已经执行完了父类
		//意味着有可能执行得哪些父类修改了bd
		// 所以下次get得时候需要合并而不是直接从merged当中直接拿
		beanFactory.clearMetadataCache();
	}

这段代码非常长,注释也很多,仔细看,再联系我之前说的这个方法主要做的两件事。

 

注释写的很明白了,先执行各个BeanDefinitionRegistryPostProcessor再执行各个BeanFactoryPostProcessor。

在前面有文章写过,spring在这个方法之前会在spring里添加几个bd,而这些bd也可能实现了这两个接口,而且这两个接口还是父子接口的关系,还有就是实现BeanDefinitionRegistryPostProcessor的bd,可以重写其方法,向spring里面再注册bd,想想如果注册进来的bd又实现了这个接口,然后还有实现了这两个接口的类,又实现了PriorityOrdered或Ordered的接口,他们也会有先后顺序,所以这段代码才会写的这么复杂。

 

而实现BeanFactoryPostProcessor接口的类,可以做的事情就是修改spring里面的bd,所以再后面得执行beanFactory的clearMetadataCache()

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值