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

Spring如何实现组件扫描与@Component注解原理

Spring如何实现组件扫描与@Component注解原理

  • 注解配置与包扫描的实现机制
    • 一、概述:什么是注解配置与包扫描?
    • 二、处理流程概览
    • 三、注解定义
      • @Component
      • @Scope
    • 四、核心代码结构
      • 1. `ClassPathScanningCandidateComponentProvider`
      • 2. `ClassPathBeanDefinitionScanner`

源码见:mini-spring

在这里插入图片描述

注解配置与包扫描的实现机制

一、概述:什么是注解配置与包扫描?

在基于注解的 Spring 样式容器中,包扫描(Package Scanning)与注解配置(Annotation Configuration) 是核心的自动化注册机制:

本质上,它通过扫描指定包路径下的类,识别其中包含特定注解(如 @Component, @Scope),并将其自动注册为容器中的 Bean。


二、处理流程概览

要实现注解注册 Bean 的机制,大致流程如下:

  1. 确定扫描路径:通常由配置文件(如 XML)提供;

  2. 扫描类文件:获取指定包路径下所有类;

  3. 筛选目标类:识别包含目标注解的类,如 @Component

  4. 构建 BeanDefinition:为每个匹配类生成对应的 BeanDefinition;

  5. 注册 BeanDefinition:将生成的 BeanDefinition 注册到 BeanDefinitionMap 中。

此流程应发生在 BeanDefinition 的加载阶段,因此其集成逻辑最终应写入 XmlBeanDefinitionReader 中。我们可以将功能模块解耦为:

  • 扫描器模块:负责扫描、识别和构建 BeanDefinition;

  • 注册器集成:负责注册这些 BeanDefinition。


三、注解定义

@Component

用于标记一个类为容器可管理的组件:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {String value() default "";
}

@Scope

用于定义组件的作用域(如 singleton / prototype):

@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Scope {String value() default "singleton";
}

四、核心代码结构

1. ClassPathScanningCandidateComponentProvider

用于扫描指定包路径下所有带 @Component 注解的类,并构建对应的 BeanDefinition:

public class ClassPathScanningCandidateComponentProvider {public Set<BeanDefinition> findCandidateComponents(String basePackage) {Set<BeanDefinition> candidates = new LinkedHashSet<>();Set<Class<?>> classes = ClassUtil.scanPackageByAnnotation(basePackage, Component.class);for (Class<?> clazz : classes) {candidates.add(new BeanDefinition(clazz));}return candidates;}
}

2. ClassPathBeanDefinitionScanner

继承扫描器,实现更完整的处理逻辑:

  • 解析作用域(@Scope);

  • 解析 Bean 名称(默认类名首字母小写);

  • 完成 BeanDefinition 的注册。

public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {private final BeanDefinitionRegister register;public ClassPathBeanDefinitionScanner(BeanDefinitionRegister register) {this.register = register;}public void doScan(String... basePackages) {for (String basePackage : basePackages) {Set<BeanDefinition> candidates = super.findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {// 设置作用域String scope = resolveBeanScope(candidate);if (StrUtil.isNotEmpty(scope)) {candidate.setScope(scope);}// 设置 Bean 名称并注册String beanName = determineBeanName(candidate);register.registerBeanDefinition(beanName, candidate);}}}private String determineBeanName(BeanDefinition definition) {Class<?> clazz = definition.getBeanClass();Component component = clazz.getAnnotation(Component.class);String value = component.value();return StrUtil.isEmpty(value) ? StrUtil.lowerFirst(clazz.getSimpleName()) : value;}private String resolveBeanScope(BeanDefinition definition) {Scope scope = definition.getBeanClass().getAnnotation(Scope.class);return scope != null ? scope.value() : StrUtil.EMPTY;}
}

相关文章:

Spring如何实现组件扫描与@Component注解原理

Spring如何实现组件扫描与Component注解原理 注解配置与包扫描的实现机制一、概述&#xff1a;什么是注解配置与包扫描&#xff1f;二、处理流程概览三、注解定义ComponentScope 四、核心代码结构1. ClassPathScanningCandidateComponentProvider2. ClassPathBeanDefinitionSca…...

历年四川大学计算机保研上机真题

2025四川大学计算机保研上机真题 2024四川大学计算机保研上机真题 2023四川大学计算机保研上机真题 在线测评链接&#xff1a;https://pgcode.cn/school 分数求和 题目描述 有一分数序列&#xff1a; 2 / 1 2/1 2/1, 3 / 2 3/2 3/2, 5 / 3 5/3 5/3, 8 / 5 8/5 8/5, 13 /…...

gcc符号表生成机制

符号表生成机制 我们以C语言的编译链接过程为例&#xff0c;详细讲解符号表&#xff08;Symbol Table&#xff09;的流程&#xff0c;涵盖编译和链接两个阶段。理解符号表是理解链接器如何解决符号引用&#xff08;如函数、变量&#xff09;的关键。 符号表分为两种&#xff…...

达梦数据库 Windows 系统安装教程

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…...

unix/linux source 命令,其基本概念、定义、性质、定理

从计算机科学的角度,特别是形式语言、操作系统和编程语言设计的角度来看,source (或 .) 命令虽然看似简单,但其背后也蕴含着一些核心的概念、定义、性质和可以类比的“定理”(或者说,更准确地是“设计原则”或“行为模式”)。 让我们尝试从一个更理论和结构化的视角来剖…...

【Java EE初阶】计算机是如何⼯作的

计算机是如何⼯作的 计算机发展史冯诺依曼体系&#xff08;Von Neumann Architecture&#xff09;CPU指令&#xff08;Instruction&#xff09;CPU 是如何执行指令的&#xff08;重点&#xff09; 操作系统&#xff08;Operating System&#xff09;进程(process) 进程 PCB 中的…...

RAG理论基础总结

目录 概念 流程 文档收集和切割 读取文档 转换文档 写入文档 向量转换和存储 搜索请求构建 向量存储工作原理 向量数据库 文档过滤和检索 检索前 检索 检索后 查询增强和关联 QuestionAnswerAdvisor查询增强 高级RAG架构 自纠错 RAG&#xff08;C-RAG&#xf…...

列表推导式(Python)

[表达式 for 变量 in 列表] 注意&#xff1a;in后面不仅可以放列表&#xff0c;还可以放range ()可迭代对象 [表达式 for 变量 in 列表 if 条件]...

嵌入式RTC工作原理及应用场景

20ppm 是衡量 RTC&#xff08;实时时钟&#xff09;精度的关键指标&#xff0c;表示 每百万秒&#xff08;约11.57天&#xff09;的最大时间误差范围。以下是通俗易懂的解释&#xff1a; 1. ppm 的含义 ppm Parts Per Million&#xff08;百万分之一&#xff09; 1 ppm 1/1,…...

一天搞懂深度学习--李宏毅教程笔记

目录 1. Introduction of Deep Learning1.1. Neural Network - A Set of Function1.2. Learning Target - Define the goodness of a function1.3. Learn! - Pick the best functionLocal minimaBackpropagation 2. Tips for Training Deep Neural Network3. Variant of Neural…...

Go语言常见接口设计技巧-《Go语言实战指南》

在 Go 中&#xff0c;接口是连接代码组件的桥梁。合理设计接口可以大幅提升程序的可维护性、可扩展性和测试友好性。本章将分享 Go 开发中常见的接口设计技巧与最佳实践。 一、接口设计原则 1. 面向接口编程&#xff0c;而非面向实现编程 尽量使用接口类型作为函数参数或返回值…...

python打卡训练营打卡记录day43

复习日 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 数据集来源&#xff1a;Flowers Recognition 选择该数据集原因&#xff1a; 中等规模&#xff1a;4242张图片 - 训练快速但足够展示效…...

Camera相机人脸识别系列专题分析之十一:人脸特征检测FFD算法之低功耗libvega_face.so人脸属性(年龄,性别,肤色,微笑,种族等)检测流程详解

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:Camera相机人脸识别系列专题分析之十:人脸特征检测FFD算法之低功耗libvega_face.so人脸识别检测流程详解 这一篇我们开始讲: Camera相机人脸识别系列专题分析之十一:人脸特征检测FFD算法之低功耗lib…...

解决:输入SSH后,仍无法通过网址登录以及紧接着的新问题Permission denied(publickey,password).

现象&#xff1a; 管理员: Windows PowerShell输入SSH后&#xff0c;仍无法通过网址登录 例如输入你的ssh命令&#xff1a;ssh -CNg -L xxxx:127.0.0.1:xxxx rootaaaaaaaaa.com -p yyyyy 得到终端提示&#xff1a;ssh无法识别为 cmdlet、函数、脚本文件或可运行程序的名称。 解…...

【QT控件】QWidget 常用核心属性介绍 -- 万字详解

目录 一、控件概述 二、QWidget 核心属性 2.1 核心属性概览 2.2 enabled ​编辑 2.3 geometry 2.4 windowTitle 2.5 windowIcon 使用qrc文件管理资源 2.6 windowOpacity 2.7 cursor 2.8 font ​编辑 2.9 toolTip 2.10 focusPolicy 2.11 styleSheet QT专栏&…...

uniapp-商城-77-shop(8.2-商品列表,地址信息添加,级联选择器picker)

地址信息,在我们支付订单上有这样一个接口,就是物流方式,一个自提,我们就显示商家地址。一个是外送,就是用户自己填写的地址。 这里先说说用户的地址添加。需要使用到的一些方式方法,主要有关于地址选择器,就是uni-data-picker级联选择。 该文介绍了电商应用中地址信息处…...

HTTPS加密通信详解及在Spring Boot中的实现

HTTPS&#xff08;Hyper Text Transfer Protocol Secure&#xff09;是HTTP的安全版本&#xff0c;通过SSL/TLS协议为通讯提供加密、身份验证和数据完整性保护。 一、HTTPS核心原理 1.加密流程概述 客户端发起HTTPS请求&#xff08;连接到服务器443端口&#xff09;服务器返…...

如何让 Git 停止跟踪文件?停止后又如何恢复跟踪?

在使用 Git 管理代码时&#xff0c;有时我们希望某些文件不再被 Git 跟踪&#xff08;比如本地配置文件、临时文件等&#xff09;&#xff0c;但保留这些文件在本地&#xff1b;过了一段时间&#xff0c;可能又需要恢复跟踪这些文件。本文将用通俗易懂的语言&#xff0c;教你如…...

【第16届蓝桥杯 | 软件赛】CB组省赛第二场

个人主页&#xff1a;Guiat 归属专栏&#xff1a;算法竞赛 文章目录 A. 密密摆放&#xff08;5分填空题&#xff09;B. 脉冲强度之和&#xff08;5分填空题&#xff09;C. 25 之和D. 旗帜E. 数列差分F. 树上寻宝G. 翻转硬币H. 破解信息 正文 总共8道题。 A. 密密摆放&#xff0…...

SQL进阶之旅 Day 10:执行计划解读与优化

【SQL进阶之旅 Day 10】执行计划解读与优化 开篇 今天是我们的"SQL进阶之旅"系列的第10天&#xff0c;我们将深入探讨SQL执行计划的解读与优化技巧。随着数据库规模的增长和业务复杂度的提升&#xff0c;理解SQL语句在数据库引擎中的执行过程变得至关重要。 执行计…...

AR/MR实时光照阴影开发教程

一、效果演示 1、PICO4 Ultra MR 发光的球 2、AR实时光照 二、实现原理 PICO4 Ultra MR开发时&#xff0c;通过空间网格能力扫描周围环境&#xff0c;然后将扫描到的环境网格材质替换为一个透明材质并停止扫描&#xff1b;基于Google ARCore XR Plugin和ARFoundation进行安卓手…...

Visual studio 中.sln/.vcxproj/.vcxproj.filters和.vcxproj.user文件的作用

在 Visual Studio (尤其是 C 项目) 中&#xff0c;.sln、.vcxproj、.vcxproj.filters 和 .vcxproj.user 文件各自承担着不同的关键角色。理解它们的作用对于项目管理和协作至关重要。 核心原则&#xff1a; .vcxproj 和 .sln 是项目/解决方案的核心定义文件&#xff0c;必须纳…...

【汽车电子入门】一文了解LIN总线

前言&#xff1a;LIN&#xff08;Local Interconnect Network&#xff09;总线&#xff0c;也就是局域互联网的意思&#xff0c;它的出现晚于CAN总线&#xff0c;于20世纪90年代末被摩托罗拉、宝马、奥迪、戴姆勒、大众以及沃尔沃等多家公司联合开发&#xff0c;其目的是提供一…...

JVM学习(七)--JVM性能监控

目录 一、JVM性能监控 1、JVM监控及诊断工具-命令行篇 2、JVM监控及诊断工具-GUI篇 3、JVM运行时参数 一、JVM性能监控 1、JVM监控及诊断工具-命令行篇 面试题&#xff1a; 1、你使用过Java虚拟机性能监控和故障处理工具吗? 2、怎么打出线程栈信息。 3、怎么获取 Jav…...

关于 java:5. Java IO 与文件操作

一、File 类&#xff08;读取文件属性&#xff09; 1.1 java.io.File 类概述 File 是 Java IO 中的核心类&#xff0c;用于表示文件或目录的路径名。 它是一个抽象路径名&#xff0c;可以表示实际存在或不存在的文件/文件夹。 File 类提供了创建、删除、重命名、判断属性、获…...

【笔记】为 Python 项目安装图像处理与科学计算依赖(MINGW64 环境)

&#x1f4dd; 为 Python 项目安装图像处理与科学计算依赖&#xff08;MINGW64 环境&#xff09; &#x1f3af; 安装目的说明 本次安装是为了在 MSYS2 的 MINGW64 工具链环境中&#xff0c;搭建一个完整的 Python 图像处理和科学计算开发环境。 主要目的是支持以下类型的 Pyth…...

【笔记】MLA矩阵吸收分析

文章目录 一、张量运算的计算量1. FLOPs定义2. 张量计算顺序对计算量的影响 二、MLA第一次矩阵吸收的计算量分析1. 原始注意力计算2. MLA源代码中的吸收方式3. 提前吸收4. 比较分析4.1 比较顺序1和顺序24.2 比较顺序2和顺序3 三、MLA第二次矩阵吸收的计算量分析1. 原始输出计算…...

600+纯CSS加载动画一键获取指南

CSS-Loaders.com 完整使用指南&#xff1a;600纯CSS加载动画库 &#x1f3af; 什么是 CSS-Loaders.com&#xff1f; CSS-Loaders.com 是一个专门提供纯CSS加载动画的资源网站&#xff0c;拥有超过600个精美的单元素加载器。这个网站的最大特色是所有动画都只需要一个HTML元素…...

开源的JT1078转GB28181服务器

JT1078转GB28181流程 项目地址&#xff1a; JT1078转GB28181的流媒体服务器: https://github.com/lkmio/lkm JT1078转GB28181的信令服务器: https://github.com/lkmio/gb-cms 1. 创建GB28181 UA 调用接口: http://localhost:9000/api/v1/jt/device/add 请求体如下&#xf…...

智能守护电网安全:探秘输电线路测温装置的科技力量

在现代电力网络的庞大版图中&#xff0c;输电线路如同一条条 “电力血管”&#xff0c;日夜不息地输送着能量。然而&#xff0c;随着电网负荷不断增加&#xff0c;长期暴露在户外的线路&#xff0c;其线夹与导线在电流热效应影响下&#xff0c;极易出现温度异常。每年因线路过热…...