spring源码之invokeBeanFactoryPostProcessors()方法解析

这一章要讲一讲,上次打断点的方法。这个方法非常重要,是我们揭开spring源码的必经之路。
AnnotationConfigApplicationContext.refresh().invokeBeanFactoryPostProcessors()

在这里插入图片描述
可以看到博主在里面写了一个注释,“执行所有可靠的BeanFactoryPostProcessors”。
想要理解这句话,首先要明白什么是BeanFactoryPostProcessors?
按照字面意思的话,很明显,就是Bean工厂的处理器,执行各种各样对于Bean内容的处理。比如上一章看到beanDefinitionMap中就有处理Bean里面Autowired注解的处理器。
再说另外一个词“可靠”,对于spring来说,什么BeanFactoryPostProcessors是可靠的呢。
有两种方式,一种是被扫描到的,一种是被手动通过Api添加的,在启动的时候都会被执行。

@Component
public class A implements BeanFactoryPostProcessor {


	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("a-p scan postProcessBeanFactory");

	}
}

public class B implements BeanFactoryPostProcessor {


	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("b-p api parent postProcessBeanFactory");

	}
}

	@Test
	public void defaultContext(){
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.addBeanFactoryPostProcessor(new B());
		context.refresh();
	}

我们在实现BeanFactoryPostProcessors一个是通过BeanFactoryPostProcessors这个类。
也可以通过BeanFactoryPostProcessors的子类 BeanDefinitionRegistryPostProcessor来实现。
他们两个都有默认的方法,我们实现的时候必须要重写的。
那么问题就来了,是到底先执行哪个的实现方法?先执行子类的实现,还是先执行父类的实现?
通过扫描和通过Api交给spring的两个类,会先执行哪个?
下面就来根据这些问题写一些测试代码。

/**
 * 通过扫描注册
 * 继承父类BeanFactoryPostProcessor
 */
@Component
public class A implements BeanFactoryPostProcessor {


	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("a-p scan postProcessBeanFactory");

	}
}


/**
 * 通过api注册
 * 继承父类BeanFactoryPostProcessor
 */
public class B implements BeanFactoryPostProcessor {


	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("b-p api parent postProcessBeanFactory");

	}
}

/**
 * 通过api注册
 * 继承子类BeanDefinitionRegistryPostProcessor
 */
public class C implements BeanDefinitionRegistryPostProcessor {


	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("c-s api parent postProcessBeanFactory");
	}

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		System.out.println("c-s api subclass postProcessBeanDefinitionRegistry");
	}
}


/**
 * 通过扫描注册
 * 继承子类BeanDefinitionRegistryPostProcessor
 * 并且手动通过注册Bean的方法处理了E,F类
 */
@Component
public class D implements BeanDefinitionRegistryPostProcessor {


	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("d-s api parent postProcessBeanFactory");
	}

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		System.out.println("d-s api subclass postProcessBeanDefinitionRegistry registry E, F");
		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(E.class);
		registry.registerBeanDefinition("e", builder.getBeanDefinition());

		BeanDefinitionBuilder FBuilder = BeanDefinitionBuilder.genericBeanDefinition(F.class);
		registry.registerBeanDefinition("f", FBuilder.getBeanDefinition());
	}
}


/**
 * 通过BeanDefinition方式注册
 * 继承父类BeanFactoryPostProcessor
 */
public class E implements BeanFactoryPostProcessor {


	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("e-p bd parent postProcessBeanFactory");

	}
}



/**
 * 通过BeanDefinition方式注册
 * 继承子类BeanDefinitionRegistryPostProcessor
 */
public class F implements BeanDefinitionRegistryPostProcessor {


	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("f-s bd parent postProcessBeanFactory");
	}

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		System.out.println("f-s bd subclass postProcessBeanDefinitionRegistry");
	}
}


/**
 * 通过扫描的方式注册
 * 继承父类BeanFactoryPostProcessor
 * 并且继承了Spring会进行判断的PriorityOrdered
 */
@Component
public class H implements BeanFactoryPostProcessor, PriorityOrdered {


	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("h-p scan parent postProcessBeanFactory PriorityOrdered");

	}

	@Override
	public int getOrder() {
		return 0;
	}
}



/**
 * 通过扫描的方式注册
 * 继承子类BeanDefinitionRegistryPostProcessor
 * 并且继承了Spring会进行判断的PriorityOrdered
 */
@Component
public class I implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {


	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("I-s scan parent postProcessBeanFactory PriorityOrdered");
	}

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		System.out.println("I-s scan subclass postProcessBeanDefinitionRegistry PriorityOrdered");
	}

	@Override
	public int getOrder() {
		return 0;
	}
}

	@Test
	public void defaultContext(){
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.scan("com.spring.context.bfpp");
		context.addBeanFactoryPostProcessor(new B());
		context.addBeanFactoryPostProcessor(new C());
		context.refresh();
	}



然后来看这个方法是如何实例化和执行这几个类的,
在这里插入图片描述
在这里插入图片描述

我把所有这个方法中的代码一行行解析,添加了注释,跟着流程走一步就懂了。
看看[A, B, C, D, E, F, H, I]这些类到底是什么时候执行的父类,什么时候执行的子类

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

		//这里保证子类和父类的方法不会重复执行
		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		//在spring源码这里基本就是百分百会进来,beanFactory始终实现了BeanDefinitionRegistry接口
		if (beanFactory instanceof BeanDefinitionRegistry) {

			//转为BeanDefinitionRegistry是为了后面动态注册BeanDefinition
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

			//存储所有实现BeanFactoryPostProcessor的Bean  也就是实现父类的Bean
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();

			//存储所有实现BeanDefinitionRegistryPostProcessor 的Bean  也就是实现子类的Bean
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			//这里循环需要处理的类,因为这时候还没有执行扫描,前面我们说过这个方法处理完之后才会扫描
			// 所以这里面只有 B、C两个类
			//只有这两个类是我们通过Api直接塞进来的
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				//判断是否继承了子类BeanDefinitionRegistryPostProcessor
				//C会进这里
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					//强转为子类,直接回调了子类的方法,然后进入registryProcessors子类的集合
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					//B类会进这里,没有做任何事情,直接添加进子类的集合
					regularPostProcessors.add(postProcessor);
				}
			}
			/**
			 * 这个时候regularPostProcessors 中有[B]
			 * registryProcessors 中有[C]  并且C类已经回调了子类的方法
			 */


			// 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.
			//根据类型查询,到beanDefinitionMap中,看有哪些类继承了子类,这里只会找到一个ConfigurationClassPostProcessor
			//在初始化beanDefinitionMap的时候只有它继承了子类,上一章讲了初始化时候里面有5个类
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				//判断是否实现了PriorityOrdered接口 这里为true
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					//通过getBean()方法实例化出来ConfigurationClassPostProcessor
					//然后放到需要执行的集合中
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					//表示已经处理完了
					processedBeans.add(ppName);
				}
			}
			//排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			//合并到子类的集合中,都执行完了为什么要放到子类集合中呢?
			//这里回调了子类方法,但是没有执行父类方法,放在这里就是等着未来回调父类方法
			registryProcessors.addAll(currentRegistryProcessors);
			//遍历回调子类postProcessBeanDefinitionRegistry方法
			//方法具体执行的内容,我们一会也会详细讲,这里只需要知道执行了就可以了
			//并且执行完ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()这个方法,就完成了扫描
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			//清空执行集合,留着以后继续用
			currentRegistryProcessors.clear();

			/**
			 * 这个时候regularPostProcessors 父类集合 中有[B]
			 * registryProcessors 中有[C, ConfigurationClassPostProcessor] 并且都已经回调了子类的方法
			 * processedBeans 处理完成的集合[ConfigurationClassPostProcessor]
			 * 并且已经完成了扫描
			 */

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			//再次从beanDefinitionMap中,获取继承子类的对象,
			//因为已经完成了扫描,所以这次可以获取到[currentRegistryProcessors, D, I]
			//并且 D:实现了子类,I:实现了子类并且实现了PriorityOrdered
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				//判断是否已经处理过了,上面在处理currentRegistryProcessors的时候把它加进了processedBeans集合中,那么第一次循环的时候不会进去
				//第二次循环D类肯定不在,但是没有实现Ordered接口,所以也不会进入这个判断
				//第三次循环I类既没有执行过,也实现了Ordered接口,所以会进这个判断
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					//这里也是通过getBean()实例化出I类,并且放入执行集合中
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					//放入已处理完集合
					processedBeans.add(ppName);
				}
			}
			//排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			//合并到子类的集合中,等待回调父类
			registryProcessors.addAll(currentRegistryProcessors);
			//回调子类方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			//清空当前执行集合
			currentRegistryProcessors.clear();

			/**
			 * 这个时候regularPostProcessors 父类集合 中有[B]
			 * registryProcessors 中有[C, ConfigurationClassPostProcessor, I] 并且都已经回调了子类的方法
			 * processedBeans 处理完成的集合[ConfigurationClassPostProcessor, I]
			 * 并且已经完成了扫描
			 */

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			/**
			 * 这里通过一个死循环,继续寻找继承了子类的对象,
			 * 上面已经找过两次了,为什么这里还有死循环找第三次?
			 * 两个原因:
			 * 第一是因为子类回调的方法可以动态注册新的BeanDefinitionPostProcessors,这里面的类是扫描不到的,只有回调完子类的方法之后才能发现。
			 * 第二个原因,在上次找的时候,找到了D和I两个类,但是只执行了I类,D类还没有执行
			 *
			 */
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				//第一次死循环,找到[currentRegistryProcessors, D, I]
				//第二次死循环,找到[currentRegistryProcessors, D, I, F] , 为什么没有找到E? 因为E实现的是父类
				//第三次死循环,找到[currentRegistryProcessors, D, I, F]
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					//第一次死循环,currentRegistryProcessors和 I已经执行了,所以只有D会进去
					//第二次死循环,找到[currentRegistryProcessors, D, I, F],只有F会进去,其他都执行过了
					//第三次死循环,找到[currentRegistryProcessors, D, I, F],没有可以进去的
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						//找到就放入已执行集合
						processedBeans.add(ppName);
						//如果找到了,就还需要进行下一次死循环,因为无法保证子类没有注册新的BeanDefinitionPostProcessors,所以就要继续找
						reiterate = true;
					}
				}
				//第一次死循环,这里只拿到了D进行处理
				//第二次死循环,这里只拿到了F进行处理
				//第三次死循环,不会执行这里
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				//第一次死循环,D在执行子类方法的时候,注册了E和F两个类
				//第二次死循环,F的子类方法只打印了日志,没有注册新的类
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			/**
			 * 这个时候regularPostProcessors 父类集合 中有[B]
			 * registryProcessors 子类集合 中有[C, ConfigurationClassPostProcessor, I, D, F] 并且都已经回调了子类的方法
			 * processedBeans 处理完成的集合[ConfigurationClassPostProcessor, I, D, F]
			 * 并且已经完成了扫描
			 */

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			//这里是执行registryProcessors继承子类集合中,所有类的父类方法
			//registryProcessors 子类集合 中有[C, ConfigurationClassPostProcessor, I, D, F]
			//在这里都回调了父类方法
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

			//执行父类集合中,所有类的父类方法
			//regularPostProcessors 父类集合 中有[B]
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			//这里在spring框架中都不会进来
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}


		/**
		 * 这个时候regularPostProcessors 父类集合 中有[B]  已经回调了父类方法
		 * registryProcessors 子类集合 中有[C, ConfigurationClassPostProcessor, I, D, F] ,并且父类子类方法都已经执行
		 * processedBeans 处理完成的集合[ConfigurationClassPostProcessor, I, D, F]
		 * 并且已经完成了扫描
		 */



		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		//找到所有继承了父类的对象[A, E, H]
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		//存储所有实现了PriorityOrdered接口的父类集合
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		//存储所有实现了Ordered接口的父类集合,需要注意的是priorityOrdered是Ordered的子类,所有进上面那个集合的对象,也会进这个集合
		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)) {
				//H类会进这里
				//为什么只有这里实例化了
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				//A会进入这里
				//E也会进入这里
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		//排序
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		//实现了priorityOrdered的优先执行父类方法 H
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		//orderedPostProcessorNames这个为空,所以不会执行
		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.
		//这里执行了A和E两个对象
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			//实例化
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		//执行H和E的父类方法
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		/**
		 * 这个时候regularPostProcessors 父类集合 中有[B]  已经回调了父类方法
		 * registryProcessors 子类集合 中有[C, ConfigurationClassPostProcessor, I, D, F] ,并且父类子类方法都已经执行
		 * processedBeans 处理完成的集合[ConfigurationClassPostProcessor, I, D, F]
		 * 并且已经完成了扫描
		 * priorityOrderedPostProcessors 集合中有[H] 已经回调了父类方法
		 * nonOrderedPostProcessors 集合中有[A,E] 已经回调了父类方法
		 *
		 * 到这里为止,所有继承了父类BeanFactoryPostProcessor和子类BeanDefinitionRegistryPostProcessor的对象都已经处理完毕了,
		 * 现在明白具体的执行顺序了吧
		 *
		 */


		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		//这个方法是相当难的,后面会详细解析
		beanFactory.clearMetadataCache();
	}

总结:
先处理子类,并且要优先执行实现了PriorityOrdered接口的类
并且先执行通过API注入的C类,
然后是扫描到的继承了PriorityOrdered接口的 “I”类
最后执行扫描到的D类,以及被子类方法注册的F类,中的子类方法

执行所有继承子类的父类方法[C, ConfigurationClassPostProcessor, I, D, F]
执行当前继承子类的父类方法[B]

接着处理父类
扫描所有继承父类的方法,通过注解注入的只有[A, E, H]

先执行继承PriorityOrdered接口的H类
在执行继承Ordered接口的类,无
最后执行A和E的父类方法

问题解析:

为什么子类BeanDefinitionRegistryPostProcessor可以动态注册新的processor而父类BeanFactoryPostProcessor不可以?为什么不开放(不建议使用)这个功能?
答:因为子类会循环调用,一直到所有的注册processor类全都执行完,而父类不会,父类回调方法之后,直接就结束了。
虽然父类确实可以动态注册新的processor,但是新的processor里面需要执行的方法和扫描之类的却不会执行。

为什么实现order接口的先执行getBean()?
答:因为实现了Order接口的类,可以认为比其他类高一级,会先执行类中的方法,有可能会改变其他类,所以要等实现Order接口类执行完成之后,才能实例化其他类。

既然实现子类BeanDefinitionRegistryPostProcessor可以动态注册类,那为什么我们之前手写mybatis的时候,会使用ImportBeanDefinitionRegistrar接口来动态注册mapper呢,两者有什么区别?
答:新版的mybatis中,ImportBeanDefinitionRegistrar实现的接口并没有动态注册mapper,而是动态注册了一个processor,由这个处理器来扫描所有的mapper。(老版的mybatis中ImportBeanDefinitionRegistrar方法直接完成了扫描和注册mapper)
ImportBeanDefinitionRegistrar实现的接口是在优先处理手动注入processor类的时候就会执行了,所以优先级是很高的。

mybatis新版和老版的区别就是
老版ImportBeanDefinitionRegistrar直接扫描和注册mapper
而新版则是在ImportBeanDefinitionRegistrar中注册了processor类,然后通过spring源码里面的执行顺序去完成扫描和注册。

为什么mybatis一定要使用ImportBeanDefinitionRegistrar?
要获取注解中的包路径,如果直接使用processor类的话无法获取。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木小同

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值