当前位置: 首页 > news >正文

【Spring类路径Bean定义信息扫描】

Spring类路径Bean定义信息扫描

  • 1. ClassPathBeanDefinitionScanner作用
  • 2. 类声明
  • 3. 属性
  • 4. 构造器
  • 5. 扫描方法
  • 6. 真正扫描方法
  • 7. postProcessBeanDefinition
  • 8. 注册bean定义

1. ClassPathBeanDefinitionScanner作用

扫描类路径下的类注册为bean定义。

2. 类声明

public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider
/**类名就是扫描类路径下bena定义。继承自类路径扫描候选组件提供器类路径扫描候选组件提供器的作用:扫描类路径下的时候,使用过滤器是否考虑作为候选者,作为待注入的bean定义。
**/

3. 属性

	// beanDefinition注册器private final BeanDefinitionRegistry registry;// 存储默认的BeanDefinition属性值,如作用域(scope)、懒加载(lazy initialization)等设置。private BeanDefinitionDefaults beanDefinitionDefaults = new BeanDefinitionDefaults();// 定义了一组字符串模式,用于决定哪些被扫描到的类应该被认为是自动装配候选者(autowire 	// candidates)。如果一个类的全限定名匹配这些模式之一,那么它将被视为可以进行自动装配的bean。private String[] autowireCandidatePatterns;// Bean名称生成器策略,默认是AnnotationBeanNameGenerator实例,它根据类上的注解或类名来生// 成bean的名称.在扫描和注册bean的过程中,会用到这个策略来生成唯一的bean名称。private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;// 指定了作用域元数据解析器,默认使用AnnotationScopeMetadataResolver,它根据类上的注解// (如@Component、@Service等)来确定bean的作用域(例如singleton或prototype)。private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();// 如果为true,表示在扫描过程中不仅会处理带有特定注解(如@Component、@Repository、@Service、// @Controller等)的类,还会处理类上的注解配置信息(如@Autowired、@Value等)。如果设置为//	false,则只扫描并注册类本身作为bean,而不处理注解驱动的配置。private boolean includeAnnotationConfig = true;

4. 构造器

/*单个参数的构造器: 传入注册器
*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {// 调用本地构造器: 注册器,使用默认过滤器this(registry, true);
}/*双参数的构造器: 传入注册器, 是否使用默认过滤器
*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {// 调用本地构造器: 注册器, 是否使用默认的过滤器,获取或创建环境this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment) {// 调用本地构造器:注册器,过滤器,环境,资源加载器(null)this(registry, useDefaultFilters, environment,(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}// 最终的构造器: 注册器、默认过滤器、环境、资源加载器
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment, @Nullable ResourceLoader resourceLoader) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");this.registry = registry;// 设置值if (useDefaultFilters) {registerDefaultFilters();}setEnvironment(environment);setResourceLoader(resourceLoader);
}

5. 扫描方法

// 扫描指定包的类
public int scan(String... basePackages) {// 获取当前注册器中bean定义的数量int beanCountAtScanStart = this.registry.getBeanDefinitionCount();// 去扫描指定的包doScan(basePackages);// Register annotation config processors, if necessary.if (this.includeAnnotationConfig) {AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}// 返回注册后-之前已注册数量的差return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}

6. 真正扫描方法

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();for (String basePackage : basePackages) {// 查找候选组件Set<BeanDefinition> candidates = findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {// 获取作用域ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);// 设置作用域candidate.setScope(scopeMetadata.getScopeName());// 按照beanName生成策略获取到bean名称String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);// 如果是抽象BeanDefinitionif (candidate instanceof AbstractBeanDefinition) {postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}// 如果是注解BeanDefinitionif (candidate instanceof AnnotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}// 检查给定的候选BeanDefinition,确定相应的BeanDefinition是否需要注册或者是否和// 已经存在的定义发生了冲突。if (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);registerBeanDefinition(definitionHolder, this.registry);}}
}

补充一下:
AbstractBeanDefinition、AnnotatedBeanDefinition都是spring框架中定义和处理BeanDefinition的类,他们在SpringIOC容器的核心机制中有重要的地位。

  • 1. AbstractBeanDefinition:
    • 是个抽象类,实现了 BeanDefinition 接口,为BeanDefinition提供了一些通用的方法和属性。
    • 提供了BeanDefinition的基本结构,如作用域scope,初始化方法,销毁方法、依赖项管理等元数据信息的存储和操作
    • 子类有:RootBeanDefinition、GenericBeanDefinition
  • 2. AnnotatedBeanDefinition:
    • 该类封装了一个被注解标注的类的信息,并能够从类上的注解提取Bean的元数据,如作用域、生命周期回调方法等。
    • 在基于注解的配置环境下,Spring会使用 AnnotatedBeanDefinitionReader 或者 ClassPathBeanDefinitionScanner 等工具将带有注解的类转换为 AnnotatedBeanDefinition 对象并注册到IoC容器中。

7. postProcessBeanDefinition

protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {beanDefinition.applyDefaults(this.beanDefinitionDefaults);if (this.autowireCandidatePatterns != null) {beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));}
}

8. 注册bean定义

protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}

相关文章:

【Spring类路径Bean定义信息扫描】

Spring类路径Bean定义信息扫描 1. ClassPathBeanDefinitionScanner作用2. 类声明3. 属性4. 构造器5. 扫描方法6. 真正扫描方法7. postProcessBeanDefinition8. 注册bean定义 1. ClassPathBeanDefinitionScanner作用 扫描类路径下的类注册为bean定义。2. 类声明 public class …...

Ubuntu上安装VMware+win11系统手册

Ubuntu安装vmware 下载&#xff1a; Linux 版下载地址&#xff1a;https://www.vmware.com/go/getworkstation-linux 安装&#xff1a; sudo chmod x VMware-Workstation-Full-17.5.0-22583795.x86_64.bundle 执行安装命令&#xff1a; sudo ./VMware-Workstation-Full-17.5.0…...

2024年1月12日:清爽无糖rio留下唇齿之间的香甜

友利奈绪的时间管理 2024年1月12日08:02:28进行java程序设计的上课准备 2024年1月12日08:02:44知道java的题目有18道 2024年1月12日08:43:07随机数去重比较 2024年1月12日08:54:03C语言题目最小公倍数 2024年1月12日08:58:37C语言题目二维数组变一维数组 2024年1月12日10…...

群晖Synology Drive同步文件时过滤指定文件夹“dist“, “node_modules“

群晖Synology Drive同步文件时过滤指定文件夹"dist", “node_modules” mac用户 安装Synology Drive创建同步任务修改Synology Drive配置 打开/Users/[用户名]/Library/Application Support/SynologyDrive/data/session/[同步任务序号&#xff0c;第一个同步任务就…...

小程序中滚动字幕

需求&#xff1a;在录像时需要在屏幕上提示字幕&#xff0c;整体匀速向上滚动 html部分&#xff1a; <view class"subtitles_main"><view style"font-size:34rpx;color: #fff;line-height: 60rpx;" animation"{{animation}}">人生的…...

MySQL中约束是什么?

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…...

若依在表格中如何将字典的键值转为中文

文章目录 一、需求&#xff1a;二、问题解决步骤1、给需要转换的列绑定formatter属性2、获取字典项3、编写formatter属性绑定的方法 一、需求&#xff1a; 后端有时候返回的是字典的键值&#xff0c;在前端展示时需要转成中文值 后端返回的是dictValue&#xff0c;现在要转换…...

用笨办法-刻意练习来提高自己的编程能力

尝试了很多学习方法&#xff0c;企图快速提高编程能力&#xff0c;但最终发现&#xff0c;唯有老老实实刻意练习1&#xff0c;在辛苦与时间积累下&#xff0c;逐渐提升能力&#xff0c;才是最有效的方式。 将自己的笨办法总结了一下&#xff0c;主要包含7个步骤&#xff1a; …...

FineBI报表页面大屏小屏自适应显示问题

大屏正常显示 显示正常 小屏BI自适应显示 存在遮挡字体情况 小屏浏览器缩放显示 等比缩放后显示正常...

NAND Separate Command Address (SCA) 接口命令解读

CA output packet和CA input packet是Separate Command Address (SCA) NAND接口协议中用于命令和地址传输的关键数据结构。 CA Input Packet: 在SCA接口中&#xff0c;输入到NAND器件的命令和地址信息被组织成并行至串行转换的CA&#xff08;Command and Address&#xff09;输…...

Git的简单使用说明

Git入门教程 git的最主要的作用&#xff1a;版本控制&#xff0c;协助开发 一.版本控制分类 ​​ 1.本地版本控制 ​​ 2.集中版本控制 ​​ 所有的版本数据都存在服务器上&#xff0c;用户的本地只有自己以前所同步的版本&#xff0c;如果不连网的话&#xff0c;用户就看不…...

少儿编程 2023年12月电子学会图形化编程等级考试Scratch二级真题解析(判断题)

2023年12月scratch编程等级考试二级真题 判断题(共10题,每题2分,共20分) 26、声音Medieval1的长度是9.68秒,运行下列程序1或程序2都能实现,播放声音2秒后,声音停止角色移动100步 答案:对 考点分析:考查积木综合使用,重点考查声音积木的使用 程序1中用的是等待播完…...

前端面试 -- vue系列

Vue系列 1. vue理解&#xff1a;2. SPA&#xff08;单页面应用理解&#xff09;3. vue实例挂载的过程4. v-for和v-if优先级5. SPA首屏加载速度慢的原因和解决办法6. Vue中给对象添加新属性界面不刷新&#xff08;直接给对象添加属性&#xff09;7. vue组件之间的通信方式有哪些…...

open3d相关操作总结

open3d其实有很多交互式命令&#xff0c;在运行程序打开了open3d渲染的窗口后&#xff0c;鼠标点击窗口&#xff0c;按H就会弹出&#xff0c;交互命令的帮助&#xff0c;如下图所示&#xff1a; 其中比较常用的有&#xff1a; Q &#xff1a;退出当前窗口 H&#xff1a;打印帮…...

HTTP数据请求

文章目录 1 概述2 什么是HTTP3 如何发起HTTP请求4 参考链接 1 概述 日常生活中我们使用应用程序看新闻、发送消息等&#xff0c;都需要连接到互联网&#xff0c;从服务端获取数据。例如&#xff0c;新闻应用可以从新闻服务器中获取最新的热点新闻&#xff0c;从而给用户打造更…...

孩子兄弟结构体【】

#include <stdio.h> typedef int TElemType; typedef struct CSTNode {TElemType data;struct CSTNode* firstChild;struct CSTNode* nextSibling; }CSTNode,*CSTree;...

SSM-SpringMVC+Spring+Mybatis

创建项目 创建好 项目后, 项目目录分析 数据库设计 我们采用员工表 Employee 与 部门表 Department 部门表 表设计--- 员工表 --表设计 因为有文件上传操作,因此 建立 info表 (其中 员工只能隶属一个部门,因此 两张表之间 有外键关系) java 代码 设计 数据库建立完毕后,需要…...

系统存储架构升级分享 | 京东云技术团队

一、业务背景 系统业务功能&#xff1a;系统内部进行数据处理及整合, 对外部系统提供结果数据的初始化(写)及查询数据结果服务。 系统网络架构: 部署架构对切量上线的影响 - 内部管理系统上线对其他系统的读业务无影响分布式缓存可进行单独扩容, 与存储及查询功能升级无关通过…...

OpenCV-22高斯滤波

一、高斯函数的基础 要理解高斯滤波首先要直到什么是高斯函数&#xff0c;高斯函数是符合高斯分布的&#xff08;也叫正态分布&#xff09;的数据的概率密度函数。 高斯函数的特点是以x轴某一点&#xff08;这一点称为均值&#xff09;为对称轴&#xff0c;越靠近中心数据发生…...

实现LCM在docker之间的通信

目录 1.docker容器互联 新建网络 连接容器 2.设置环境变量 3.在两个docker之间实现通信 1.docker容器互联 新建网络 $ docker network create -d bridge test-net 连接容器 运行一个容器并连接到新建的 test-net 网络: $ docker run -itd --name lcm_1 --network tes…...

GitLab任意用户密码重置漏洞(CVE-2023-7028)

GitLab CVE-2023-7028 POC user[email][]validemail.com&user[email][]attackeremail.com 本文链接&#xff1a; https://www.黑客.wang/wen/47.html...

在机械行业中,直线导轨和弧形导轨哪个应用范围更广泛?

弧形导轨和直线导轨是两种常见的导轨类型&#xff0c;直线导轨主要被用于高精度或快速直线往复运动场所&#xff0c;而弧形导轨是一种专门设计用于曲线运动的导轨系统&#xff0c;那么在机械行业中&#xff0c;直线导轨和弧形导轨哪个应用范围更加广泛呢&#xff1f; 直线导轨主…...

关于ue4 射击游戏架构设计

传统mmo的服务器架构 网关--->游戏逻辑服--->游戏db服 网关---> 游戏逻辑服--->关系服务器master 其结构简单&#xff0c;方便维护&#xff0c;但是在应对射击游戏时候暴露出很大的缺陷 但是随着大dau产品的像和平精英等游戏问世 腾讯主要的服务器是基于tbus4j…...

vc++开发地图

1、概述 &#xff08;1&#xff09;mapbox 官网&#xff1a;https://docs.mapbox.com/mapbox-gl-js/example/ github: https://github.com/mapbox/mapbox-gl-native (2)mapX 使用VC创建MapX控件步骤 在vc中作用mapx C 如何根据地理坐标范围获取瓦片地图并使用CImage库实现多张…...

轻量化的yolov8部署到安卓Android手机端

一、pytorch环境配置和yolov8源码安装 首先在电脑上需要配置好pytorch环境&#xff0c;和yolov8源码的下载 然后针对yolov8做自己的轻量化改进 二、下载Android Studio和ncnn-android-yolov8 1. Android Studio官网链接&#xff1a; 下载 Android Studio 和应用工具 - And…...

分块矩阵的定义、计算

目录 一、定义 二、分块矩阵的加减乘法 三、考点 一、定义 分块&#xff0c;顾名思义&#xff0c;将整个矩阵分成几部分&#xff0c;如下图所示 二、分块矩阵的加减乘法 三、考点 分块矩阵的考点不多&#xff0c;一般来说&#xff0c;有一种&#xff1a; 求分块矩阵的转置…...

NAND系统性能提升常见方案

随着NAND的发展&#xff0c;针对NAND系统性能提升&#xff0c;业内目前主要的做法有以下几种方案&#xff1a; 1.提升总线频率和优化AC时序&#xff1a; 提高NAND闪存接口的工作频率可以显著加快数据传输速度。通过不断改进工艺和技术&#xff0c;缩短了信号稳定时间、降低了延…...

集简云动作管理平台上线:创建强大且可分享的AI助手(GPTs)

OpenAI的GPT Store于昨天上线&#xff0c;用户可以找到好用的GPTs&#xff0c;也可以将自己的GPTs分享到GPT Store中。未来&#xff08;预计今年1季度&#xff09;甚至可以从GPTs Store中获取利润分成。 要创建强大的GPTs离不开调用外部的软件工具&#xff0c;比如查询CRM/ERP软…...

机器人制作开源方案 | 基于混合现实的可移动机械臂平台

作者&#xff1a;董泽宇 李肖兵 叶彤 李秉宸 吴雅霏 单位&#xff1a;广西大学 电气工程学院 指导老师&#xff1a;李勇 雷圆媛 为应对特殊条件下不便于实地进行移动式操作的问题&#xff0c;本作品设计了一套基于混合现实的可移动机械臂操作控制系统。该系统分为人机交互、机…...

JavaScript基础03

1 - 循环 1.1 for循环 语法结构 for(初始化变量; 条件表达式; 操作表达式 ){//循环体 } 名称作用初始化变量通常被用于初始化一个计数器&#xff0c;该表达式可以使用 var 关键字声明新的变量&#xff0c;这个变量帮我们来记录次数。条件表达式用于确定每一次循环是否能被执行…...

手机维修网站那个公司做的/深圳推广

先并查集&#xff0c;然后最小生成树&#xff0c;最短路&#xff0c;强连通&#xff0c;双连通&#xff0c;LCA&#xff0c;二分匹配&#xff0c;网络流&#xff0c;2-sat 这部分搞完后&#xff0c;开始树直径&#xff0c;树重心&#xff0c;欧拉回路&#xff0c;树分治 转载于…...

php网站开发实训指导书/百度点击软件名风

继北京、上海后&#xff0c;近日&#xff0c;华为鸿蒙OS 2.0手机开发者Beta活动在广州举行。在此次活动现场&#xff0c;华为智慧全场景业务部副总裁段孟然再次公布了鸿蒙OS手机版的重磅消息。段孟然称&#xff0c;自去年年底正式发布面向手机开发者的鸿蒙OS Beta版本后&#x…...

wordpress宝宝网商城免费模板下载/it行业培训机构一般多少钱

前言&#xff1a;负责&#xff0c;因为该项目他(jetty嵌入式开始SpringMvc)实现文件上传的必要性&#xff0c;并拥有java文件上传这一块还没有被曝光。并 Http 更多晦涩协议。因此&#xff0c;这种渐进的方式来学习和实践上载文件的原则。 该博客侧重于实践。 一.Http协议原理简…...

做网站怎样做才有百度快照/网站推广的渠道有哪些

仔细看看现在的招聘&#xff0c;在多大多数招聘中都要向你的代码面向对象&#xff0c;这是必须的。 不管对于初学者还是老手来说&#xff0c;很多人对面向对象都掌握得不是想像的那么好&#xff0c;那我们应该如何学习面向对象呢&#xff1f; 面向对象他是一种思想&#xff0c;…...

怎么看网站创建者是谁/帮别人发广告赚钱平台

TOM 科技讯美国东部时间 10 月 20 日(北京时间 10 月 21 日)据外电的最新报道&#xff0c;市场调研公司 IDC 最新的调查结果显示&#xff0c;Linux 操作系统用户是全球操作系统用户中最忠实的操作系统用户。一旦使用该操作系统之后&#xff0c;只有很少一部分 Linux 操作系统用…...

做网站的公司怎么推销/移动端排名优化软件

求开4个线程4秒内执行完以下程序&#xff1b;部分代码已标注不能修改 1 public class LogTest {2 // 里面的方法不能动3 public static void parseLog(String log) {4 System.out.println(log ":" (System.currentTimeMillis() / 1000));5 …...