spring复习:(24)ApplicationContext中的BeanPostProcess是在哪里注册到容器的?

news2024/11/25 11:48:58

在ApplicationContext实现类的构造方法里。

	public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}

上边的构造方法调用如下构造方法

	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}

在其中调用的refresh()方法中代码如下:

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

其中图示的部分完成了BeanPostProcessor的注册:
在这里插入图片描述
registerBeanPostProcessors代码如下:

	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

其中会通过代理类PostProcessorRegistrationDelegate代理类来注册BeanPostProcessor.

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

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

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

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

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

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

可见,BeanPostProcessor分为3类:
priorityOrderdPostProcessors
oderedPostProcessors
noOrderedPostProcessors

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

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

相关文章

ubuntu使用WHEELTE N100并用rviz显示

写在最开头&#xff0c;如果wheeltec n100被自己改动过参数导致无法读取数据&#xff0c;建议在window的上位机中恢复出厂设置并重新上电&#xff0c;在转入ubuntu。因为我就是这个问题&#xff0c;客服远程操控才帮我解决的。 所有官方资料共享&#xff0c;侵删&#xff1a; …

Flink+StarRocks 实时数据分析新范式

摘要&#xff1a;本文整理自 StarRocks 社区技术布道师谢寅&#xff0c;在 Flink Forward Asia 2022 实时湖仓的分享。本篇内容主要分为五个部分&#xff1a; 极速数据分析 实时数据更新 StarRocks Connector For Apache Flink 客户实践案例 未来规划 点击查看原文视频 &a…

一篇文章让你看懂C语言字符函数和内存函数

目录 一、字符函数 1.strlen函数 1.1strlen函数的介绍 1.2strle函数的使用 1.3模拟实现strlen 1.3.1指针移动法 1.3.2指针减去指针法 1.3.3函数递归法 2.strcpy函数 ​编辑 2.1strcpy函数的介绍 2.2strcpy函数的使用 2.3模拟实现strcpy 3.strcat函数 3.1strcat函数的介…

LiveGBS流媒体平台GB/T28181功能-支持海康大华GB28181语音对讲需要的设备及服务准备

LiveGBS支持海康大华GB28181语音对讲需要的设备及服务准备 1、背景2、准备2.1、服务端必备条件&#xff08;注意&#xff09;2.2、准备语音对讲设备2.2.1、 大华摄像机2.2.1.1、 配置接入示例2.2.1.2、 配置音频通道编号 2.2.2、 海康摄像机2.2.2.1、 配置接入示例 3、开启音频…

初试Python路径库

文章目录 一、pathlib概述二、操作路径对象(一)操作属性(二)连接路径(三)拆分完整路径三、路径对象的常用函数(一)获取当前工作目录(二)创建新目录(三)查看主目录一、pathlib概述 自Python 3.4 以来,pathlib一直是标准库的一部分。 PurePath, PurePosixPath, Pure…

即视角|出海资本热土——印尼市场洞察(上)

即视角Insight 共享即构新洞察&#xff0c;共建行业新动能——ZEGO即构科技基于音视频技术领域的多年深耕&#xff0c;综合面向各行业的服务经验&#xff0c;在【即视角】栏目发布即构对行业的洞察。 此前我们根据即构对出海客户的服务经验&#xff0c;输出了文章《即视角&am…

STL标准模板库 set容器

文章目录 迭代器迭代器的五大分类迭代器系列帮手函数一览 set容器打印任意 STL 容器的printer.hset与vectorset 和 vector 的区别set 和 vector 迭代器的共同点set 和 vector 迭代器的不同点 set 的排序set 的排序&#xff1a;string 会按“字典序”来排set 的排序&#xff1a;…

ai智能绘画生成器有哪些?你知道ai生成图片网站哪个好吗?

曾经有一个年轻的画家&#xff0c;名叫亚历克斯。他对艺术充满了热情和渴望&#xff0c;但却常常感到自己的创作灵感有限。每当他拿起画笔&#xff0c;总是困扰于如何将心中的景象完美地呈现在画布上。 有一天&#xff0c;亚历克斯偶然听说了一个神奇的网站&#xff0c;据说这…

【力扣】20. 有效的括号

有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相…

uniapp H5预览PDF文件

1&#xff0c;下载资源后hybrid文件存放在static静态文件里 (点击这里去下载文件) 2&#xff0c;pdf预览页面配置 <template><view style"width: 100vh;"><web-view :src"pdfUrl"></web-view></view> </template><…

【每日一题】1289. 下降路径最小和 II

【每日一题】1289. 下降路径最小和 II 1289. 下降路径最小和 II题目描述解题思路 1289. 下降路径最小和 II 题目描述 给你一个 n x n 整数矩阵 grid &#xff0c;请你返回 非零偏移下降路径 数字和的最小值。 非零偏移下降路径 定义为&#xff1a;从 grid 数组中的每一行选择…

【计算机视觉】简述对EQ-Net的理解

最近又看了一些点云分割的文章&#xff0c;近两年点云分割的文章是真的少&#xff0c;不知道是不是点云分割算法接近了末端。这篇文章主要提出了一个基于查询方法的统一范式&#xff0c;它解决了一些不仅仅是点云分割的问题&#xff0c;还解决了三维点云分类和三维目标检测的问…

解密AI图像安全技术:智能守护数智时代,低代码平台助力圈复杂操作!

前言 随着数智时代的来临&#xff0c;人们进入了一个全新的智能化世界。在这个时代中&#xff0c;人工智能&#xff08;AI&#xff09;成为了一项重要的技术突破&#xff0c;其应用也无处不在。其中&#xff0c;AI图像安全技术作为保障个人和企业数据安全的重要环节&#xff0c…

Linux——认识Linux的目录结构 常用命令 vim命令 权限及其控制

目录 linux的目录结构常用linux的命令ls(list)和llcd 切换目录mkdir 创建文件夹touch命令&#xff1a;创建普通文本文件pwd 显示路径whoamisu&#xff1a;普通--超级账号man&#xff1a;查看手册rm&#xff1a;删除网络命令ifconfig重定向 >>cat 查看文本文件clear清屏hi…

3.2 Bootstrap 下拉菜单(Dropdowns)

文章目录 Bootstrap 下拉菜单&#xff08;Dropdowns&#xff09;选项对齐标题 更多实例 Bootstrap 下拉菜单&#xff08;Dropdowns&#xff09; 本章将重点介绍 Bootstrap 下拉菜单。下拉菜单是可切换的&#xff0c;是以列表格式显示链接的上下文菜单。这可以通过与 下拉菜单&a…

NZ12:VBA给批量文件重命名

【分享成果&#xff0c;随喜正能量】沉默&#xff0c;可以让混乱的心&#xff0c;变得清澈。沉默&#xff0c;是城府&#xff0c;是睿智&#xff0c;是内涵&#xff1b;沉默&#xff0c;是最后的清高&#xff0c;也是最后的自由。。 我的教程一共九套及VBA汉英手册一部&#x…

nginx添加模块fastdfs-nginx-module(docker版,不需要重写dockerfile)

nginx添加模块fastdfs-nginx-module&#xff08;docker版&#xff0c;不需要重写dockerfile&#xff09; 一、fastdfs-nginx-module模块准备1.1、下载模块1.2、配置模块参数 二、重新制作nginx的二进制执行文件2.1、查看nginx版本2.2、下载nginx配套版本的源码文件2.3、制作ngi…

线性表综合应用题2

设计一个高效算法&#xff0c;将顺序表L的所有元素逆置&#xff0c;要求算法的空间复杂度为O(1)。 算法思想&#xff1a;扫描顺序表L的前半部分元素&#xff0c;对于元素L.data[i] (0<i<L.length/2),将其与后半部分的对应元素L.data[L.length - i - 1]进行交换。 #defi…

GC overhead limit exceeded问题

GC overhead limit exceeded问题 一、为什么会产生GC overhead limit exceeded问题 OutOfMemoryError是java.lang.VirtualMachineError的子类&#xff1b;JVM遇到与资源利用有关的问题时&#xff0c;会抛出该错误。更具体地说&#xff0c;当JVM花太多时间执行垃圾回收并且只能…

807. 区间求和

链接&#xff1a; 链接 题目&#xff1a; 输入两个整数 ll 和 rr&#xff0c;请你编写一个函数&#xff0c;int sum(int l, int r)&#xff0c;计算并输出区间 [l,r][l,r] 内所有整数的和。 输入格式 共一行&#xff0c;包含两个整数 ll 和 rr。 输出格式 共一行&#xff0c;包…