spring--bean工厂后置处理器(BeanFactoryPostProcessor)原理解析

功能描述:

  • 实现BeanFactoryPostProcessor接口允许我们可以在任何bean实例化之前对bean工厂进行加工,如spring的ConfigurationClassPostProcessor类就实现了该接口,负责解析@Configuration、@ComponentScan、@ComponentScans、@Import等注解
  • BeanFactoryPostProcessor 接口定义:
    	@FunctionalInterface
    	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;
    	}
    

后置处理器加载解析

  • 这个是在创建applicationContext过程中,从抽象类AbstractApplicationContextrefresh方法开始,去除注释和日志,我们来看看源码

    	@Override
    	public void refresh() throws BeansException, IllegalStateException {
    		synchronized (this.startupShutdownMonitor) {
    			
    			prepareRefresh();
    			
    			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    			
    			prepareBeanFactory(beanFactory);
    
    			try {
    				postProcessBeanFactory(beanFactory);
    				// 调用bean工厂后置处理器
    				invokeBeanFactoryPostProcessors(beanFactory);
    				
    				registerBeanPostProcessors(beanFactory);
    				
    				initMessageSource();
    				
    				initApplicationEventMulticaster();
    				
    				onRefresh();
    				
    				registerListeners();
    				
    				finishBeanFactoryInitialization(beanFactory);
    		
    				finishRefresh();
    			} catch (BeansException ex) {
    				
    				destroyBeans();
    				
    				cancelRefresh(ex);
    				
    				throw ex;
    			} finally {
    				resetCommonCaches();
    			}
    		}
    	}
    
    

    这里我们只关心invokeBeanFactoryPostProcessors方法

invokeBeanFactoryPostProcessors方法负责调用bean工厂后置处理器

  • 源码

    	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    		// getBeanFactoryPostProcessors方法获取了所有硬编码的bean工厂处理器
    		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    
    		// 默认情况下这里判断不会为空,在refresh方法调用的prepareBeanFactory方法内已经执行过这段代码了
    		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    			// 添加bean后置处理器,负责调用实现了LoadTimeWeaverAware接口setLoadTimeWeaver方法的bean
    			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    			// 添加一个临时类加载器
    			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    		}
    	}
    
    	public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    		return this.beanFactoryPostProcessors;
    	}
    
    
  • 自定义应用上下文时可以通过手动调用addBeanFactoryPostProcessor方法添加bean工厂后置处理器

    	@Override
    	public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
    		Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
    		this.beanFactoryPostProcessors.add(postProcessor);
    	}
    
  • 核心方法 invokeBeanFactoryPostProcessors

    	public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    		// 记录所有即将或已经处理的beanName,用于防止重复处理
    		Set<String> processedBeans = new HashSet<>();
    
    		// bean工厂是否实现 BeanDefinitionRegistry 接口,需要对实现了该接口的bean工厂做被实现了 BeanDefinitionRegistryPostProcessor 接口的类的额外处理
    		if (beanFactory instanceof BeanDefinitionRegistry) {
    		
    			// 这里会对实现了 BeanDefinitionRegistryPostProcessor 接口做回调处理
    			// 所有回调过的类都会记录到 processedBeans 集合中
    			// 具体内容我们下面在讲
    			......
    			
    		} else {
    			// 执行 bean工厂处理器
    			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    		}
    
    		// 获取所有实现了 BeanFactoryPostProcessor 接口的类
    		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
    		// 统计实现了排序接口 PriorityOrdered 的类
    		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    		// 统计实现了排序接口 Ordered 的类
    		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);
    		// 调用 BeanFactoryPostProcessor 接口的 postProcessBeanFactory 方法
    		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
    		// 处理实现了 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);
    
    		// 处理无排序的类
    		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    		for (String postProcessorName : nonOrderedPostProcessorNames) {
    			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    		}
    		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
    		// 清除元数据缓存
    		beanFactory.clearMetadataCache();
    	}
    
    	private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
    
    		for (BeanFactoryPostProcessor postProcessor : postProcessors) {
    			postProcessor.postProcessBeanFactory(beanFactory);
    		}
    	}
    
    

    流程图
    在这里插入图片描述
    我们看到,在处理回调前有一个判断bean工厂是否 BeanDefinitionRegistry 类型
    如果bean工厂是 BeanDefinitionRegistry 类型的则会进入到 BeanDefinitionRegistryPostProcessor 的后置处理器过程

  • BeanDefinitionRegistryPostProcessor 接口定义

    	public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    	
    		void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
    	}
    
  • BeanDefinitionRegistryPostProcessor 处理源码

    	public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    		// 记录所有即将或已经处理的beanName,用于防止重复处理
    		Set<String> processedBeans = new HashSet<>();
    
    		// bean工厂是否实现 BeanDefinitionRegistry 接口,需要对实现了该接口的bean工厂做被实现了 BeanDefinitionRegistryPostProcessor 接口的类的额外处理
    		if (beanFactory instanceof BeanDefinitionRegistry) {
    			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    			// 最后处理
    			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    			// 标记所有待处理的类
    			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
    			// 遍历硬编码注册的处理器
    			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    				// 如果硬编码注册的处理器实现了 BeanDefinitionRegistryPostProcessor 接口,则立即调用 postProcessBeanDefinitionRegistry 方法,否则放到最后处理
    				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    					BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
    					registryProcessor.postProcessBeanDefinitionRegistry(registry);
    					registryProcessors.add(registryProcessor);
    				}
    				else {
    					regularPostProcessors.add(postProcessor);
    				}
    			}
    
    			// 某一次循环的缓存集合,如:先处理所有实现了 PriorityOrdered 接口的类,再处理所有实现了 Ordered 接口的类
    			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
    			// 获取所有实现了 BeanDefinitionRegistryPostProcessor 接口的类
    			String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    			for (String ppName : postProcessorNames) {
    				// 判断是否未处理过且类实现了 PriorityOrdered 接口
    				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    					// 获取bean实例,并加入到接下来要处理的类的集合中
    					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					// 标记处理
    					processedBeans.add(ppName);
    				}
    			}
    			// 根据 PriorityOrdered 接口排序
    			sortPostProcessors(currentRegistryProcessors, beanFactory);
    			// 添加到 bean工厂处理器
    			registryProcessors.addAll(currentRegistryProcessors);
    			// 执行 bean定义处理器
    			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    			// 清空当前处理过的数据
    			currentRegistryProcessors.clear();
    
    			// 获取所有实现了 BeanDefinitionRegistryPostProcessor 接口的类
    			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    			for (String ppName : postProcessorNames) {
    				// 判断是否未处理过且类实现了 Ordered 接口
    				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    					// 获取bean实例,并加入到接下来要处理的类的集合中
    					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					// 标记处理
    					processedBeans.add(ppName);
    				}
    			}
    			// 根据 Ordered 接口排序
    			sortPostProcessors(currentRegistryProcessors, beanFactory);
    			// 添加到 bean工厂处理器
    			registryProcessors.addAll(currentRegistryProcessors);
    			// 执行 bean定义处理器
    			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    			// 清空当前处理过的数据
    			currentRegistryProcessors.clear();
    
    			// 标记是否在某一次循环中有处理过数据,如果有,则可能会新增实现了 BeanDefinitionRegistryPostProcessor 接口的 bean,所以需要循环执行,直到某次获取的类全部都是处理过的
    			boolean reiterate = true;
    			while (reiterate) {
    				reiterate = false;
    				// 获取所有实现了 BeanDefinitionRegistryPostProcessor 接口的类
    				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    				for (String ppName : postProcessorNames) {
    					// 判断是否未处理过
    					if (!processedBeans.contains(ppName)) {
    						// 获取bean实例,并加入到接下来要处理的类的集合中
    						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    						// 标记处理
    						processedBeans.add(ppName);
    						// 有处理到数据,再循环一遍
    						reiterate = true;
    					}
    				}
    				// 可能存在后面新增的类存在排序接口,所以这里也要排序
    				sortPostProcessors(currentRegistryProcessors, beanFactory);
    				// 添加到 bean工厂处理器
    				registryProcessors.addAll(currentRegistryProcessors);
    				// 执行 bean定义处理器
    				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    				// 清空当前处理过的数据
    				currentRegistryProcessors.clear();
    			}
    
    			// 批量调用 BeanFactoryPostProcessor 接口的 postProcessBeanFactory 方法
    			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    		}
    
    		else {
    			// 执行 bean工厂处理器
    			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    		}
    
    		......
    	}
    

    BeanDefinitionRegistryPostProcessor 处理过程与 BeanFactoryPostProcessor 类似,
    但是由于是先执行 BeanDefinitionRegistryPostProcessor 的后置处理器再获取BeanFactoryPostProcessor 的后置处理器,所以 BeanDefinitionRegistryPostProcessor 处理时可添加新的后置处理器,BeanFactoryPostProcessor则不行,还有一个原因是 BeanDefinitionRegistryPostProcessor 每次都会调用 beanFactory.getBeanNamesForType 方法获取最新的后置处理器

    实现了 BeanDefinitionRegistryPostProcessor 接口的类还是会调用 BeanFactoryPostProcessor接口的 postProcessBeanFactory方法

总结

  1. BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor 都可以通过实现 PriorityOrdered 或 Ordered 接口进行排序
  2. 依次处理完 BeanDefinitionRegistryPostProcessor 接口回调后处理 BeanFactoryPostProcessor 接口回调
  3. BeanDefinitionRegistryPostProcessor 处理过程中新注册 BeanFactoryPostProcessor 或 BeanDefinitionRegistryPostProcessor(注意优先级) 后置处理器会生效,反之 BeanFactoryPostProcessor 处理过程中新增则不会生效
  4. 硬编码添加的后置处理器没有优先级区分,会根据加入顺序最早触发回调
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring中的前置处理器后置处理器是用来在Bean的实例化和初始化过程中进行一些额外的处理的。前置处理器BeanFactoryPostProcessor接口的实现类,它在Spring容器加载Bean的定义之后,实例化Bean之前进行一些配置的修改或者其他操作。它可以对Bean的定义进行解析和修改,最终将修改后的Bean定义添加到SpringBeanDefinitionMap中。\[1\]后置处理器BeanPostProcessor接口的实现类,它在Bean的实例化和初始化过程中,对Bean进行一些额外的处理。它可以在Bean实例化后对Bean进行修改,也可以在Bean初始化前后对Bean进行一些操作,比如动态代理等。\[2\]在调用前置处理器的时候,Spring会按照优先级进行分类调用。实现了PriorityOrdered接口的前置处理器会先被调用,然后是实现了Ordered接口的前置处理器,最后是没有实现这两个接口的前置处理器。\[3\]这样可以确保前置处理器按照指定的顺序进行调用,以满足不同的需求。 #### 引用[.reference_title] - *1* *3* [攀登Spring珠穆朗玛峰:前置与后置处理器](https://blog.csdn.net/qq_38289451/article/details/122226807)[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^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Spring Bean前置后置处理器的使用](https://blog.csdn.net/weixin_40834464/article/details/82832173)[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^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值