spring复习:(52)注解方式下,ConfigurationClassPostProcessor是怎么被添加到容器的?

进入AnnotationConfigApplicationContext的构造方法:

进入AnnotatedBeanDefinitionReader的构造方法:

进入this(registry, getOrCreateEnvironment(registry));代码如下:

进入AnnotationConfigUtils.registerAnnotationConfigProcessors方法:

点击进入其重载的方法:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition();try {def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));}catch (ClassNotFoundException ex) {throw new IllegalStateException("Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);}def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}return beanDefs;}
其中包含如下代码:

可以看到调用了registerPostProcessor注册了类型为ConfigurationClassPostProcessor的bean,registerPostProcessor代码如下:

其中调用的registerBeanDefinition的代码如下:
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {Assert.hasText(beanName, "Bean name must not be empty");Assert.notNull(beanDefinition, "BeanDefinition must not be null");if (beanDefinition instanceof AbstractBeanDefinition) {try {((AbstractBeanDefinition) beanDefinition).validate();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Validation of bean definition failed", ex);}}BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);if (existingDefinition != null) {if (!isAllowBeanDefinitionOverriding()) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);}else if (existingDefinition.getRole() < beanDefinition.getRole()) {// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTUREif (logger.isInfoEnabled()) {logger.info("Overriding user-defined bean definition for bean '" + beanName +"' with a framework-generated bean definition: replacing [" +existingDefinition + "] with [" + beanDefinition + "]");}}else if (!beanDefinition.equals(existingDefinition)) {if (logger.isDebugEnabled()) {logger.debug("Overriding bean definition for bean '" + beanName +"' with a different definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}else {if (logger.isTraceEnabled()) {logger.trace("Overriding bean definition for bean '" + beanName +"' with an equivalent definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}this.beanDefinitionMap.put(beanName, beanDefinition);}else {if (hasBeanCreationStarted()) {// Cannot modify startup-time collection elements anymore (for stable iteration)synchronized (this.beanDefinitionMap) {this.beanDefinitionMap.put(beanName, beanDefinition);List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames = updatedDefinitions;removeManualSingletonName(beanName);}}else {// Still in startup registration phasethis.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);removeManualSingletonName(beanName);}this.frozenBeanDefinitionNames = null;}if (existingDefinition != null || containsSingleton(beanName)) {resetBeanDefinition(beanName);}}
其中包含了如下代码:

从红线处可以看到,直接向beanDefinitionMap 进行了put,也就完成了向容器注册ConfigurationClassPostProcessor类的bean
相关文章:
spring复习:(52)注解方式下,ConfigurationClassPostProcessor是怎么被添加到容器的?
进入AnnotationConfigApplicationContext的构造方法: 进入AnnotatedBeanDefinitionReader的构造方法: 进入this(registry, getOrCreateEnvironment(registry));代码如下: 进入AnnotationConfigUtils.registerAnnotationConfigProcessors方…...
全国大学生数据统计与分析竞赛2021年【本科组】-B题:用户消费行为价值分析
目录 摘 要 1 任务背景与重述 1.1 任务背景 1.2 任务重述 2 任务分析 3 数据假设 4 任务求解 4.1 任务一:数据预处理 4.1.1 数据清洗 4.1.2 数据集成 4.1.3 数据变换 4.2 任务二:对用户城市分布情况与分布情况可视化分析 4.2.1 城市分布情况可视化分析 4…...
力扣1667. 修复表中的名字
表: Users ------------------------- | Column Name | Type | ------------------------- | user_id | int | | name | varchar | ------------------------- 在 SQL 中,user_id 是该表的主键。 该表包含用户的 ID 和名字。…...
【设计模式】详解观察者模式
文章目录 1、简介2、观察者模式简单实现抽象主题(Subject)具体主题(ConcreteSubject)抽象观察者(Observer)具体观察者(ConcrereObserver)测试: 观察者设计模式优缺点观察…...
用html+javascript打造公文一键排版系统8:附件及标题排版
最近工作有点忙,所 以没能及时完善公文一键排版系统,现在只好熬夜更新一下。 有时公文有包括附件,招照公文排版规范: 附件应当另面编排,并在版记之前,与公文正文一起装订。“附件”二字及附件顺序号用3号黑…...
微服务体系<1>
我们的微服务架构 我们的微服务架构和单体架构的区别 什么是微服务架构 微服务就是吧我们传统的单体服务分成 订单模块 库存模块 账户模块单体模块 是本地调用 从订单模块 调用到库存模块 再到账户模块 这三个模块都是调用的同一个数据库 这就是我们的单体架构微服务 就是…...
M5ATOMS3基础02传感器MPU6886
M5ATOMS3基础01按键 简洁版本 MPU6886是一款6轴IMU单元,具有3轴重力加速度计和3轴陀螺仪。它采用16位ADC,内置可编程数字滤波器和片上温度传感器,并通过I2C接口(地址为0x68)与上位机通信。MPU6886支持低功耗模式&#…...
vue 快速自定义分页el-pagination
vue 快速自定义分页el-pagination template <div style"text-align: center"><el-paginationbackground:current-page"pageObj.currentPage":page-size"pageObj.page":page-sizes"pageObj.pageSize"layout"total,prev,…...
0-虚拟机补充知识
虚拟机克隆 如果想要构建服务器集群,没有必要一台一台的去进行安装,只要通过克隆就可以。 快速获得多台服务器主要有两种方式,分别为:直接拷贝操作和vmware的克隆操作 直接拷贝 将之前安装虚拟机的所有文件进行拷贝࿰…...
如何将电机控制器添加到您的 ROS 机器人
一、说明 如果您正在构建与 ROS/ROS2 一起使用的移动机器人,您需要做的第一件事就是集成电机控制器。电机控制器的目的是接受来自更高级别的软件(如导航堆栈)的消息,并将其转换为驱动电机的信号。它还将从电机的编码器接收信息,以计算机器人的速度和位置。 您可以…...
ChatGPT统计“一到点就下班”的人数
ChatGPT统计“一到点就下班”的人数 1、到点下班 Chatgpt统计各部门F-D级员工到点下班人数占比,是在批评公司内部存在到点下班现象。 根据图片,该占比的计算方法是:最后一次下班卡在17:30-17:40之间,且1-5月合计有40天以上的人…...
Games101学习笔记 - 变换矩阵基础
二维空间下的变换 缩放矩阵 缩放变换: 假如一个点(X,Y)。x经过n倍缩放,y经过m倍缩放,得到的新点(X1,Y1);那么新点和远点有如下关系,X1 n*X, Y1 m*Y写成矩阵就是如下…...
Ubuntu18.04未安装Qt报qt.qpa.plugin could not load the Qt platform plugin xcb问题的解决方法
在Ubuntu 18.04开发机上安装了Qt 5.14.2,当将其可执行程序拷贝到另一台未安装Qt的Ubuntu 18.04上报错:拷贝可执行程序前,使用ldd将此执行程序依赖的动态库也一起拷贝过去,包括Qt5.14.2/5.14.2/gcc_64/plugins目录系的platforms目录…...
GPT4ALL私有化部署 01 | Python环境
进入以下链接: https://www.python.org/downloads/release/python-3100/ 滑动到底部 选择你系统对应的版本,如果你是win,那么大概率是win-64bit 有可能你会因为网络的问题导致下载不了,我提供了 链接 接着只需要打开 等待…...
GPT-AI 使用的技术概览
ChatGPT 使用的技术概览 智心AI-3.5/4模型,联网对话,MJ快速绘画 从去年 OpenAI 发布 ChatGPT 以来,AI 的能力再次惊艳了世人。在这样的一个时间节点,重新去学习相关技术显得很有必要。 ChatGPT 的内容很多,我计划采用…...
NoSQL-Redis持久化
NoSQL-Redis持久化 一、Redis 高可用:1.概述: 二、Redis持久化:1.持久化的功能:2.Redis 提供两种方式进行持久化: 三、RDB 持久化:1.定义:2.触发条件:3.执行流程:4.启动时…...
关于uniapp中的日历组件uni-calendar中的小红点
关于uniapp中的日历组件uni-calendar中的小红点 如果你使用过uni-calendar组件,可能你觉得这个小红点有点碍眼,但是官方给定的日历组件uni-calendar中如果你想要在某一天上添加一些信息例如:价格,签到,打卡之类,只要标…...
【Nodejs】Node.js简介
1.前言 Node 的重要性已经不言而喻,很多互联网公司都已经有大量的高性能系统运行在 Node 之上。Node 凭借其单线程、异步等举措实现了极高的性能基准。此外,目前最为流行的 Web 开发模式是前后端分离的形式,即前端开发者与后端开发者在自己喜…...
SpringBoot整合Druid
在Spring Boot中整合Druid时,需要导入Druid和JDBC的相关依赖,但不需要额外导入单独的JDBC包。 Druid是一个用于数据库连接池和监控的开源框架,它已经包含了对JDBC的实现。因此,当你导入Druid的依赖时,它已经包含了对J…...
mysql(二)SQL语句
目录 一、SQL语句类型 二、数据库操作 三、数据类型 四、创建 五、查看 六、更改 七、增、删、改、查 八、查询数据 一、SQL语句类型 SQL语句类型: DDL DDL(Data Definition Language,数据定义语言):用于…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
