【源码解析】Spring源码解读-beanFactory和Bean的后置处理器流程

news2024/11/22 19:48:43

在这里插入图片描述
上一篇文章,我们详细介绍了spring是如何通过加载xml配置文件,将beanfactry创建成功的,接着核心流程,我们继续说下beanFactory和Bean的后置处理流程。

				//留给子类的模板方法,允许子类继续对工厂执行一些处理; Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				//【大核心】工厂增强:执行所有的BeanFactory后置增强器;利用BeanFactory后置增强器对工厂进行修改或者增强,配置类会在这里进行解析。 Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				//【核心】注册所有的Bean的后置处理器 Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

postProcessBeanFactory

invokeBeanFactoryPostProcessors 方法是核心,改方法主要是通过获取beanFactoryPostProcessors的所有子类。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		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 (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

核心方法是invokeBeanFactoryPostProcessors

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

		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
			//先拿到底层默认有的BeanFactoryPostProcessor
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// 首先:从工厂中获取所有的实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor; First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //拿到系统中每一个组件的BD信息,进行类型对比,是否匹配指定的类型
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//从工厂中获取这个组件【getBean整个组件创建的流程】并放到这个集合
					processedBeans.add(ppName);
				}
			} //下面利用优先级排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); //执行这些BeanDefinitionRegistryPostProcessor的
			currentRegistryProcessors.clear();

			// 接下来,获取所有实现了Ordered接口的 BeanDefinitionRegistryPostProcessor Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			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); //即使实现了 PriorityOrdered 和Ordered,也是以 PriorityOrdered
				}
			}//排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); //执行
			currentRegistryProcessors.clear();

			// 最后,我们自定义的一般没有任何优先级和排序接口   Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);//拿到所有的BeanDefinitionRegistryPostProcessor
				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(); //防止重复执行
			}

			// 接下来,再来执行postProcessBeanFactory的回调, Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}
		//以前在执行 BeanDefinitionRegistryPostProcessor ,以后来执行 BeanFactoryPostProcessor
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

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

		// 首先执行所有实现了 PriorityOrdered 的 BeanFactoryPostProcessor;First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 接下来执行,实现了 Ordered 接口的 BeanFactoryPostProcessor  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);

		// 最后执行没有任何优先级和排序接口的 BeanFactoryPostProcessor 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); //执行所有的 BeanFactoryPostProcessor
		beanFactory.clearMetadataCache();
	}

主要流程其实是先拿到底层默认有的BeanFactoryPostProcessor,然后在获取 从工厂中获取所有的实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor,接下来,获取所有实现了Ordered接口的 BeanDefinitionRegistryPostProcessor

BeanPostProcessors

	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
		//获取到容器中所有的 BeanPostProcessor; Bean的后置处理器
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		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)) {  //获取所有实现了 PriorityOrdered 的 BeanPostProcessor
				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);
			}
		}

		//首先,注册所有的实现了 PriorityOrdered 的 BeanPostProcessor ;  First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		//接下来,注册所有的实现了 Ordered 的 BeanPostProcessor  Next, register the BeanPostProcessors that implement Ordered.
		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);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 最后,注册所有普通的 BeanPostProcessor ;Now, register all regular BeanPostProcessors.
		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);

		//最后,重新注册所有internal的BeanPostProcessors  Finally, re-register all internal BeanPostProcessors.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 重新注册一下这个后置处理器 Re-register post-processor for detecting inner beans as ApplicationListeners,
		// 把他放到后置处理器的最后一位; moving it to the end of the processor chain (for picking up proxies etc).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1144727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二、【海报合成的创意】

文章目录 多分析他人海报&#xff0c;逐渐学会生成自己的创意关键词创意寻找素材寻找创意灵感的网站 那么如何快速生成创意&#xff1f; 多分析他人海报&#xff0c;逐渐学会生成自己的创意 关键词创意 从上图中我们可以看到&#xff0c;该海报中主要突出的主体是耳机。突出的…

【Git企业开发】第一节.Git 的分支管理

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;Git企业级开发 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&#xff0…

java后端返回数据给前端时去除值为空或NULL的属性、忽略某些属性

目录 一、使用场景 二、环境准备 1、引入依赖 2、实体类 三、示例 1、不返回空值 (1)方式 (2)测试 (3)说明 2、不返回部分属性 (1)方式 (2)测试 一、使用场景 在开发过程中&#xff0c;有时候需要将后端数据返回前端&#xff0c;此时有些数据为空属性不需要返回&…

SSM度假村管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 SSM 度假村管理系统是一套完善的信息系统&#xff0c;结合SSM框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要 采用B/S模式开发…

[LaTeX] [数学符号] \mathbb{1}的各种替代方案:解决在 LaTeX 中输入黑板粗体的数字

[LaTeX] [数学符号] \mathbb{1}的各种替代方案&#xff1a;解决在 LaTeX 中输入黑板粗体的数字_latex mathbb-CSDN博客文章浏览阅读5w次&#xff0c;点赞36次&#xff0c;收藏80次。本文介绍如何在 LaTeX 中输入黑板粗体的数字。_latex mathbbhttps://blog.csdn.net/xovee/arti…

FRP内网穿透(待续)

FRP内网穿透技术原理&#xff1a; FRP可以将内网服务主机以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。 1.GITHUB下载FRP 2.云服务器安装FRP修改配置 3.本地计算机安装FRP修改配置

R-FCN: Object Detection via Region-based Fully Convolutional Networks(2016.6)

文章目录 AbstractIntroduction当前最先进目标检测存在的问题针对上述问题&#xff0c;我们提出... Our approachOverviewBackbone architecturePosition-sensitive score maps & Position-sensitive RoI pooling Related WorkExperimentsConclusion 原文链接 源代码 Abstr…

iOS的应用生命周期以及应用界面

在iOS的原生开发中&#xff0c;我们需要特别关注两个东西&#xff1a;AppDelegate和ViewController。我们主要的编码工作就是在AppDelegate和ViewControlle这两个类中进行的。它们的类图如下图所示&#xff1a; AppDelegate是应用程序委托对象&#xff0c;它继承了UIResponder类…

业务设计——责任链验证推翻 if-else 炼狱

责任链模式 1. 什么是责任链模式 在责任链模式中&#xff0c;多个处理器依次处理同一个请求。一个请求先经过 A 处理器处理&#xff0c;然后再把请求传递给 B 处理器&#xff0c;B 处理器处理完后再传递给 C 处理器&#xff0c;以此类推&#xff0c;形成一个链条&#xff0c;链…

Proteus仿真--左右来回流水灯仿真(仿真文件+程序)

本文主要介绍基于51单片机的流水灯仿真&#xff08;完整仿真源文件及代码见文末链接&#xff09; 仿真运行视频 Proteus仿真--基于51单片机的流水灯仿真&#xff08;左右来回&#xff09; 附完整Proteus仿真资料代码资料 百度网盘链接: https://pan.baidu.com/s/1pS1rHGOhwYgP…

springboot+vue基于协同过滤算法的私人诊所管理系统的设计与实现【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

MySQL Server 5.5 软件和安装配置教程

MySQL 5.5.58&#xff08;32/64位&#xff09;下载链接&#xff1a; 百度网盘&#xff1a;百度网盘 请输入提取码 提取密码&#xff1a;7act 软件简介&#xff1a; MySQL 是由瑞典MySQL AB 公司开发一个关系型数据库管理系统&#xff0c;目前属于 Oracle 旗下产品。MySQL 是最…

15KW永磁同步电动机设计

摘 要 在我们日常生活中&#xff0c;永磁同步电机随处可见&#xff0c;因为其相比其他电机而言结构相对简单&#xff0c;运行稳定且便于维修等优势&#xff0c;最重要的是永磁同步电机在调速方面具有很好的优势。随着自动控制技术和微电子技术的不断革新&#xff0c;目前的技术…

她从家乡自贡起步,努力奋斗进京任职

读罢“北京文博”于2023年10月14日发表的新闻报道《文明互鉴 文明共兴——2023国际城市媒体北京论坛在京举行》&#xff0c;心中甚为欣慰。因为当年从笔者家乡走出去的70后女青年吴旭&#xff0c;现在令人惊喜地已经成长为中华全国新闻工作者协会党组成员、中宣部对外推广局局长…

高等数学前置知识——一次函数

文章目录 一次函数1.1 一次函数1.2 正比例函数1.3 一次函数的平移1.4 一次函数常用知识 一次函数 1.1 一次函数 一次函数的定义为&#xff1a;y kx b &#xff0c;k ≠ 0。 ​ 注&#xff1a;在这个函数中k代表斜率&#xff0c;b代表与y轴的截距。当 x 0 时&#xff0c;y…

挖坑法,Hoare,非递归法实现快速排序

时间&#xff1a;O(N*lgn)->最坏n^2(有序&#xff0c;逆序) 空间&#xff1a;logN N*2 Hoare Hoare法与其他快速排序算法的不同之处在于它使用两个指针&#xff08;分别指向数组的起始位置和结束位置&#xff09;&#xff0c;并通过交换元素的方式来确定基准值的最终位置。…

python 安装成功后终端显示的还是低版本

如果你下载了新版的 Python&#xff0c;但在使用时发现仍然是之前的版本&#xff0c;可能是因为新版的 Python 没有替代系统环境中的旧版 Python。 检查 PATH 环境变量&#xff1a;在命令行中输入 python --version 来查看当前默认的 Python 版本。如果显示的是旧版 Python 的…

Zotero背景设置护眼模式

一、背景知识 Zotero是开源的文献管理工具&#xff0c;功能非常强大&#xff0c;可以安装多款插件。对我来说&#xff0c;其最大的优点是可以对文章分类和打标签&#xff0c;因为某个瞬间&#xff0c;我经常想起论文中的一个图片&#xff0c;或者某个细节&#xff0c;但是却记…

Android:窗口管理器WindowManager

Android&#xff1a;窗口管理器WindowManager 导言 本篇文章主要是对Android中与窗口(Window)有关的知识的介绍&#xff0c;主要涉及到的有&#xff1a; WindowWindowManagerWindowManagerService 主要是为了更进一步地向下地深入Android屏幕渲染的知识&#xff08;虽然窗口…

vlc打开网络流(如rtmp),并查看媒体信息

打开vlc 选择媒体&#xff0c;打开网络串流 输入rtmp地址&#xff0c;点击播放 选择工具-编解码信息 可以查看节目的编码信息什么的