Spring IOC 后置处理器

#博学谷IT学习技术支持#

简介

之前的章节,看了AbstractApplicationContext的refresh()中的beanDefinitions创建过程和beanFactory的准备工作。这一章节,我们一起来看下一些后置处理器。
后置处理器大家应该都听说过,Spring框架中,很多的自定义扩展都是使用后置处理器来实现的。
首先来看下后置处理有哪些:
重要分为两大类:
1.BeanFactoryPostProcessor:与BeanFactory相关的后置处理器。这个接口只有一个方法postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory),会传入beanFactory,可以针对于beanFactory做一些操作。下面会有BeanDefinitionRegistryPostProcessor,就是继承了BeanFactoryPostProcessor
2.BeanPostProcessor:与Bean相关的后置处理器。该接口有两个方法postProcessBeforeInitialization(Object bean, String beanName)和postProcessAfterInitialization(Object bean, String beanName)。
postProcessBeforeInitialization方法在创建Bean之前执行,postProcessAfterInitialization会在Bean创建后执行。实现这个接口的后置处理器,主要针对于Bean去做一些处理拓展工作。

postProcessBeanFactory方法

该方法在AbstractApplicationContext类型是空实现,交给子类来进行重写。该方法也是用于自定义处理BeanFactory的。

invokeBeanFactoryPostProcessors方法

调用BeanFactoryPostProcessor。看下代码

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		// 调用BeanFactoryPostProcessor
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
		// 以下代码主要是判断是否需要加载时织入,需要的话添加LoadTimeWeaverAwareProcessor后置处理器和临时类加载器,这块代码暂时不做介绍。有兴趣的可以去查找下资料
		if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors

方法内部看着代码比较多,但是逻辑性对比较单一,还是比较好理解的

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

		Set<String> processedBeans = new HashSet<>();
		// 判断beanFactory是否为 BeanDefinitionRegistry子类
		if (beanFactory instanceof BeanDefinitionRegistry) {
			// 强转为BeanDefinitionRegistry
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			// 遍历传递过来的beanFactoryPostProcessors
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				// 如果postProcessor是否BeanDefinitionRegistryPostProcessor接口子类的话
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					// 强转为BeanDefinitionRegistryPostProcessor
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					// 调用 BeanDefinitionRegistryPostProcessor 后置处理器的postProcessBeanDefinitionRegistry方法
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					// 添加到registryProcessors集合中
					registryProcessors.add(registryProcessor);
				}
				else {
					// 如果postProcessor 不是BeanDefinitionRegistryPostProcessor的子类,直接添加到regularPostProcessors列表中
					regularPostProcessors.add(postProcessor);
				}
			}

			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			//根据BeanDefinitionRegistryPostProcessor类型去查找beanNames
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			// 遍历postProcessorNames,ppName就是每个匹配到的BeanDefinitionRegistryPostProcessor后置处理器的beanName
			for (String ppName : postProcessorNames) {
				/**
				 * 判断当前ppName对应的Bean是否实现了PriorityOrdered接口
				 * PriorityOrdered: 实现了Ordered接口,优先级比Ordered接口要高,因此会先处理实现了改接口的后置处理器
				 * Ordered: 这个接口是Spring中的排序接口,通过getOrder获取排序顺序,值越小,优先级越大
				 */
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// 获取对应的Bean,并放入currentRegistryProcessors列表中
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			// 根据优先级顺序排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 将排序后的列表放入registryProcessors列表中
			registryProcessors.addAll(currentRegistryProcessors);
			// 执行后置处理逻辑,其实就是调用BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			// 执行完后将currentRegistryProcessors列表清空
			currentRegistryProcessors.clear();

			// 和上述步骤一样不过这次是获取的实现Ordered接口的BeanDefinitionRegistryPostProcessor Beans
			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();

			/**
			 * 执行完实现了PriorityOrdered和Ordered 接口的处理器,开始执行没有实现这两个排序接口的后置处理器
			 */
			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();
			}

			/**
			 * 因为BeanDefinitionRegistryPostProcessor接口也继承了BeanFactoryPostProcessor,
			 * 因此这里会再次调用这些后置处理器的postProcessBeanFactory方法
			 */
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// 判断beanFactory不是 BeanDefinitionRegistry子类,则只执行传入的beanFactoryPostProcessors
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// 和上述逻辑很相似,不过这里获取的是BeanFactoryPostProcessor
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
		
		// 先处理实现了PriorityOrdered接口的BeanFactoryPostProcessor,然后Ordered,然后其他
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
			}
			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);
			}
		}

		// 排序
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		// 先调用实现了PriorityOrdered接口的BeanFactoryPostProcessor
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 调用实现了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);

		// 执行其他的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
		
		// 清理缓存
		beanFactory.clearMetadataCache();
	}

这里要说下,前面说了后置处理器主要有BeanFactoryPostProcessor和BeanPostProcessor,但是这个方法BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor是分开处理的,相当于在Spring框架层面,BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor属于两种类型的后置处理器。但是因为BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,这里我也就将BeanDefinitionRegistryPostProcessor归于了BeanFactoryPostProcessor。

registerBeanPostProcessors

	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		// 先根据BeanPostProcessor类型查找beanNames
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// 记录数量
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		/**
		 * 这里也是分为PriorityOrdered,Ordered和其他
		 * 多了一个internalPostProcessors,存放的是MergedBeanDefinitionPostProcessor类型的后置处理器
		 * 其实我们就可以把这个想象成前面的BeanDefinitionRegistryPostProcessor
		 */
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// 根据beanName和类型获取相应的Bean
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 先排序priorityOrderedPostProcessors
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		// 注册后置处理器
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 获取orderedPostProcessors中beanName对应的Bean,并将MergedBeanDefinitionPostProcessor类型的处理器放入internalPostProcessors
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		// 排序orderedPostProcessors
		sortPostProcessors(orderedPostProcessors, beanFactory);
		// 注册后置处理器
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 最后处理其他没实现排序接口的BeanPostProcessor
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// 排序
		sortPostProcessors(internalPostProcessors, beanFactory);
		// 注册
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 将检测内部bean的后处理器重新注册为applicationlistener,将它移动到处理器链的末端
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

这样关于BeanFactoryPostProcessor后置处理器的调用和BeanPostProcessor后置处理器的注册就看完了。又不懂或这有问题不全面的地方,请大家积极指出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实例化后处理器是指在IOC容器中配并实例化后处理器的过程。后处理器可以分为bean的后处理器和容器的后处理器。对于bean的后处理器,它会对容器中的bean进行后处理,对bean进行增强。而对于容器的后处理器,它会对IOC容器的功能进行增强。 常见的配实例化后处理器的方法有两种: 1. 使用@Configuration注解的类中使用@Bean注解来配bean后处理器。这种方式通过在配类中定义一个方法,并使用@Bean注解标记这个方法,使其返回一个后处理器的实例。例如,可以使用@Configuration和@Bean注解来配一个ConfigurationClassPostProcessor的实例,该实例是一个bean工厂后处理器实现类,用于解析@ComponentScan和@Bean注解。 2. 使用特定的后处理器实现类来配bean工厂后处理器。例如,可以使用MapperScannerConfigurer来作为bean工厂后处理器的实现类,用于扫描指定的包,并将符合条件的类注册成bean。 配实例化后处理器的具体步骤和方法可以根据具体的需求和使用场景进行选择和配。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Spring学习理解---后处理器](https://blog.csdn.net/qq_24792035/article/details/127311732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Spring之BeanFactoryPostProcessor(bean工厂后处理器)](https://blog.csdn.net/qq_35512802/article/details/126167419)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值