为什么我只要在类上写一个 @Service 或 @Component,它就能被 Spring 管理,Spring Boot 是如何找到这些类的?

Spring @Component 注解原理与实战避坑指南 @Component 是 Spring 框架中最基础也最易被误解的组件声明机制,其本质是触发类路径扫描、BeanDefinition 注册与实例化三阶段生命周期的元数据契约。它不直接创建对象,而是通过 `@ComponentScan` 驱动容器识别候选类,再经 `AnnotatedBeanDefinitionReader` 转换为可调度的 Bean 元信息。理解其扫描路径规则、嵌套类限制、名称生成逻辑及与 `@Bean` 的分工边界,是避免空指针、AOP 失效、启动失败等高频问题的关键。在微服务与模块化架构 阅读详情

回答这个问题之前我们一定要了解 Spring Boot “约定优于配置”的理念。

答案的核心是两个概念:组件扫描(Component Scanning) 和 自动配置(Auto-Configuration)。

我们来一步步揭开这个答案。

背后的原理:我们用一个“人口普查”的案例来分析

假设 Spring Boot 启动的过程就像一个城市(你的应用程序)进行第一次人口普查。

  1. 第一步:居民亮出身份牌 (@Component, @Service等)
    你在你的类上写的 @Service, @Component, @Repository, @Controller 等注解,就像是给你的房子门口挂上了一个牌子,上面写着:“我是本市合法居民,请登记我!”。

    • @Component 是最通用的牌子。
    • @Service、@Repository、@Controller 是更具体的牌子(“我是医生”、“我是工程师”、“我是市长”),它们本质上都包含了 @Component 的功能,只是语义上更清晰。
  2. 第二步:普查员出动 (@ComponentScan)
    光有牌子没用,还需要有人去看。Spring 框架有一个“普查员”,它的名字叫 @ComponentScan。这个注解的作用就是告诉 Spring:“请到指定的区域去扫描所有挂了‘居民’牌子的类!”

  3. 第三步:普查的起点和范围 (神奇的 @SpringBootApplication)
    这时你可能会问:“可我没写 @ComponentScan 啊?”
    这正是 Spring Boot 的第一个魔法。你启动类上那个熟悉的 @SpringBootApplication 注解,其实是一个“三合一”的复合注解,它包含了:

    • @SpringBootConfiguration:表示这是一个 Spring Boot 的配置类。
    • @EnableAutoConfiguration:启用 Spring Boot 的自动配置功能(这是另一个大魔法,暂且不表)。
    • @ComponentScan:这就是答案!@SpringBootApplication 默认就帮你开启了组件扫描!

    那么,扫描的范围是哪里呢?
    约定: Spring Boot 默认会扫描 @SpringBootApplication 所在类及其所有子包(sub-packages)。

    这就是为什么我们通常会把启动类放在项目的根包(root package)下(比如 com.myapp),这样它就能自动扫描到 com.myapp.service, com.myapp.controller 等所有子包里的组件了。

    com.myapp
    ├── Application.java      <-- @SpringBootApplication 在这里,是扫描的起点
    │
    ├── controller
    │   └── MyController.java <-- 能被扫描到
    │
    ├── service
    │   └── MyService.java    <-- 能被扫描到
    │
    └── repository
        └── MyRepository.java <-- 能被扫描到
    
  4. 第四步:登记入册(注册到 IoC 容器)
    普查员 (@ComponentScan) 扫描到所有挂牌的类之后,并不会立刻使用它们。它会把这些类的“信息”报告给 Spring IoC 容器。
    容器拿到这份名单后,会通过**反射(Reflection)**机制来创建这些类的实例,并将这些实例作为 Bean 登记在册,存放在一个类似 Map 的结构中进行统一管理。

  5. 第五步:按需分配(@Autowired 依赖注入)
    现在,容器里已经有了一堆注册好的、随时可用的 Bean(比如 myServiceImpl 的实例)。
    当容器在创建另一个 Bean(比如 MyController)时,它会检查这个类的代码:

    • 它发现 MyController 有一个字段或构造函数上标注了 @Autowired private MyService myService;。
    • 这个注解的意思是:“我需要一个 MyService 类型的居民来帮我干活!”
    • 于是,容器就去它的“登记册”(那个 Map)里查找一个类型是 MyService 的 Bean。
    • 找到后,就把它“注入”(赋值)给 MyController 的 myService 字段。

至此,整个链路就完成了!

流程总结

Spring Boot 启动时:

  1. 启动 -> 看到主启动类上的 @SpringBootApplication。
  2. 发现 @ComponentScan -> 从 @SpringBootApplication 中发现内置的 @ComponentScan。
  3. 确定扫描路径 -> 将主启动类所在的包作为根路径。
  4. 执行扫描 -> 在这个路径及其子路径下,寻找所有被 @Component (及其衍生注解 @Service, @Controller 等) 标注的类。
  5. 实例化和注册 -> 将找到的类通过反射创建成实例(Bean),并放入 IoC 容器中。
  6. 依赖注入 -> 在创建 Bean 的过程中,如果发现 @Autowired 注解,就从容器中找到匹配的 Bean 并注入进去,完成对象之间的“自动装配”。

如果没有 Spring Boot 会怎么样?

在没有 Spring Boot 的“远古” Spring MVC 时代,我们需要手动完成这一切:

  1. 在 XML 配置文件中明确开启组件扫描:
    <context:component-scan base-package="com.myapp" />
    
  2. 或者在 Java 配置类中明确写上 @ComponentScan:
    @Configuration
    @ComponentScan("com.myapp")
    public class AppConfig {
        // ... 其他配置
    }
    

Spring Boot 的伟大之处在于,它通过 @SpringBootApplication 这个小小的注解,将这些过去需要手动配置的内容,变成了一种自动的、符合约定的,极大地简化了开发者的工作。我们只需要遵守把类放在正确包下的约定,其他的一切都由框架自动完成。

Spring @Component 注解底层原理与实战避坑指南 @Component 是 Spring IoC 容器最基础的组件声明机制,其本质是触发类路径扫描(ClassPathBeanDefinitionScanner)的元数据标记,而非简单语法糖。它通过 ASM 字节码解析在运行时识别注解,驱动 BeanDefinition 构建、依赖注入与生命周期管理。作为 @Service、@Repository 等语义化注解的元注解,@Component 支撑着 Spring Boot 自动装配、条件化加载(@Conditional)及模块化治理能力。深入理解其扫描边界、命 阅读详情

相关推荐

Spring的注解 @Component 和 @Service 的不同?

🏆本文收录于《滚雪球学Spring Boot》,专门攻坚指数提升,2025 年国内最系统+最强(更新中)。    本专栏致力打造最硬核 Spring Boot 从零基础到进阶系列学习内容,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…欢迎大家订阅持续学习。 如果想快速定位学习,可以看这篇【SpringBoot教程导航帖】,你想学习的都被收集在内,快速投入学习!!两不误。

**My Coding Family** 1047

详解@Autowired@Service和spring容器

@Autowired UserService userService; 实例化一个service不能new对象 而且必须加上 @Autowired注解 经行注入spring容器 除了加这个注解外 还可以 创建一个有参构造函数 @AllArgsConstructor 也能完成注入spring @Service @Transactional @AllArgsConstructor public class UserService { 在service上面加了Servic...

fanlao4203的博客 696

Spring的注解@Component和@Service的不同

Spring的注解@Component和@Service的不同

橙-极纪元-JJYCheng 451

service包中的组件无法被扫描到

Spring boot service包中的组件无法被扫描到 一般遇到service无法被扫描到有这么几个问题 serviceImpl没有添加@service注解 主程序入口的位置不正确,应该在项目的外层,这样才能扫描到与之同级的包以及子包(当然也可以添加 @ComponentScan()注解) service下层次的Mapper没有添加@Mapper 注解 直接手动扫描了某些包,导致自动扫描失效。 但本人碰到了一个十分奇怪的问题导致了无法被扫描 –在serviceImpl中写入一些测试方法使用的是Ju

花开的博客 1770

Ubuntu22.04下安装LDAP

在Ubuntu22.04的时候可以使用apt的方式来安装,在安装LDAP的web 服务器的时候可以考虑选择 LDAP 帐户管理器 (LAM)。因为 PHPLDAPadmin 安装时需要 php 的环境依赖,相对来说安装麻烦。此外在 PHPLDAPadmin 中创建组织和用户时与平常的语法有很大不同,对新手来说不友好。

dl_11的博客 3944

手把手教你用Kokoro-82M-v1.1-zh搭建本地TTS服务(含WebSocket接口)

本文详细介绍了如何使用Kokoro-82M-v1.1-zh模型搭建本地TTS服务,包括环境配置、模型部署、WebSocket接口实现及性能优化。通过实战指南,开发者可以快速掌握本地部署TTS系统的关键技术,提升语音交互应用的开发效率。

weixin_30776273的博客 183

spring boot中的标注@Component、@Service等

让我告诉你什么叫水货。

左直拳的马桶_日用桶 2439

Windows报错“The system cannot find the file specified“的PATH环境变量解决方案

摘要: Windows系统中出现"The system cannot find the file specified"错误通常因PATH环境变量配置问题导致。本文提供解决方案:1)检查并修正PATH变量(通过命令行或图形界面添加缺失路径);2)确认程序安装路径及拼写无误;3)恢复误改的系统变量。示例演示了Python路径配置及无效路径清理方法,建议谨慎修改变量、使用绝对路径并定期检查。附参考表格详述操作步骤,帮助用户高效解决问题并优化系统环境。

shejizuopin的博客 3516

Spring Boot中Stereotype注解详解 @Component @Service @Repository @Controller @RestController 以及 @Mapper

简单理解:Stereotype注解可以看作是“分类标签”。你给一个Java类贴上不同的标签(注解),Spring容器在启动时就会扫描这些标签,并根据标签的含义,自动创建这些类的对象(即Bean),并管理它们的生命周期和依赖关系。核心机制:这一切都基于Spring的组件扫描(Component Scanning)。默认情况下,Spring Boot会扫描主应用类所在包及其所有子包下的类。注解含义层主要用途@Component通用组件任意不属于其他类的通用Bean@Service业务逻辑。

BillKu的博客 1076

【Unity引擎技术整合】 Unity学习路线 | 知识汇总 | 持续更新 | 保持乐趣 | 共同成长

本文对Unity引擎的知识进行了一个整理总结,基本包含了Unity中大部分的知识介绍。 网上也有很多Unity相关的学习资料,但大多数都不成体系,学起来的时候难免会东奔西走的摸不着头脑。 本文整理的多数文章都是有对应的系列性文章专栏,可以更方便的进行系统学习相关知识体系。

努力前行,总会成为自己心中的那道光 15万+

作物生长模型Oryza V3实战9:控制文件参数详解

control.dat是ORYZA水稻模型的核心配置文件,主要包含三部分:1)基础参数设置与模拟时间定义;2)关键文件路径配置,包括土壤参数文件(soil.sol)、作物参数文件(cultivar.crp)、田间管理文件(manage.exp)及气象数据目录,同时指定输出结果文件(res.dat)和运行日志(model.log);3)可选参数和输出控制选项。该文件通过关联各类输入数据(气象、土壤、品种特性等)和输出结果,实现模型运行的全流程控制,支持参数调整后继续模拟和中断恢复功能。

221

Springboot注解 @Bean、@Component、 @Service、 @Repository 、@Controller、@Autowired @Qualifier @Primary

@Bean、@Component、 @Service、 @Repository 、 @Controller @Bean:表示一个方法实例化、配置或者初始化一个Spring IoC容器管理的新对象。 @Data @EnableConfigurationProperties @Configuration @ConfigurationProperties(prefix = "redis.cache") public class RedisCacheConfig { @Bean public Cac

u013586483的博客 1万+

【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)

生存和射击游戏一直是我的最爱,说起3D最普遍的应该就是射击系统了,你可以在任何情况下加入射击功能,所以我写下了这篇FPS开发记录。希望对你有帮助。在这个项目中,你将学习如何设计和实现射击系统、武器系统、玩家控制、场景设计等方面的内容。通过这个项目,你将深入了解游戏开发中的许多核心概念和技术,并且在实践中不断提升自己。本项目将带你从零开始逐步实现一个完整的第一人称射击游戏,并且会逐步引入一些高级功能,如特效、声音等。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 5499

Spring Boot 注解-@Repository、@Service、@Controller 和 @Component

一切的开始都是艰难的开始,只有多多思考,最终才能达成目标!! Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控...

jomes_wang的博客 986

基于STM32F4XX 、HAL库的GXHT30C温湿度传感器驱动应用C语言程序设计

define GXHT30C_STATUS_WRITE_CHK (1 << 0) // 写数据校验状态。#define GXHT30C_STATUS_HUMI_TRACK (1 << 11) // 湿度跟踪报警。#define GXHT30C_STATUS_TEMP_TRACK (1 << 10) // 温度跟踪报警。#define GXHT30C_STATUS_CMD_STATUS (1 << 1) // 命令执行状态。

PP_Cottage的博客 226

水很深的深度学习(四): 卷积神经网络CNN

深度学习-CNN,卷积神经网络的概念 上世纪60年代,Hubel等人通过对猫视觉皮层细胞的研究,提出了感受野这个概念,到80年代,Fukushima在感受野概念的基础之上提出了神经认知机的概念,可以看作是卷积神经网络的第一个实现网络,神经认知机将一个视觉模式分解成许多子模式(特征),然后进入分层递阶式相连的特征平面进行处理

专注大数据与人工智能技术分享,欢迎私信加群互相学习! 3622

Spring/Spring-Boot中@Component的作用

今天在写程序的时候看见一个以前没有见过的注解(@Component),在网上查找过后,经过实践,决定把它记录下来。 1、@controller 控制器(注入服务) 用于标注控制层,相当于struts中的action层 2、@service 服务(注入dao) 用于标注服务层,主要用来进行业务的逻辑处理 3、@repository(实现dao访问) 用于标注数据访问层,也可以说用于标注数据访问组件,即DAO组件. 4、@component (把普通pojo实例化到spring容器中,相当于配置文件中的&lt

1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Spring Boot @Component注解介绍

是 Spring 中的一个核心注解,用于声明一个类为 Spring 管理的组件(Bean)。它是一个通用的注解,可以用于任何层次的类(如服务层、控制器层、持久层等)。这些注解的作用是标记类为 Spring 的 Bean,并且可以根据注解的类型提供额外的语义信息(例如,:当一个类不属于特定的层次(如服务层、控制器层等),但需要被 Spring 管理时,可以使用。你可以在其他组件中通过。:当需要将第三方库的类注册到 Spring 容器中时,可以使用。是一个通用注解,但在实际开发中,更推荐使用更具体的注解(如。

a876106354的博客 3148

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

javaweb中@Component和@Mapper和@Service和@RestController这几个注解要加在哪?为什么?

这些注解的使用使得Spring框架能够自动识别和装配组件,极大地简化了Java Web应用的开发和配置。通过将这些注解加在相应的类上,你可以让Spring框架自动管理这些类的实例,并在需要时注入到其他组件中,从而实现依赖注入和自动装配。

zw45607076875的博客 1061

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Spring注解@Component、@Repository、@Service、@Controller区别

Spring注解@Component、@Repository、@Service、@Controller区别 所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释。 在一个稍大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找以及维护起来也不太方便。 Spring2.

wang_j_p的专栏 420

如何通过注解(@Component 等)声明一个 Bean?Spring 是如何找到这些注解的?

你做什么 (声明)Spring 做什么 (发现和管理)1. 在你的类上添加@Component或其衍生注解 (@Service等)。1. 启动时加载一个配置类 (2. 在配置类上添加,告诉 Spring 从哪里开始扫描。2. 发现注解,获取要扫描的包路径。3. 使用扫描器在指定的类路径下查找所有.class文件。4. 高效读取每个.class文件的元数据(特别是注解)。5. 识别出被@Component等注解标记的类。6. 为每个识别出的类创建一个(Bean 的蓝图/菜谱)。

专注于技术分享 796

小白理解@Service,@Component, @Controller, @Repository, @Autowired等注入

Service,@Component,@Controller 只有语义的区别,其实他们的作用都是一样的,就是说可以混用?但没人这么弄, 大家约定俗成: 服务层@Service, 控制层@Controller ,存储层@Repository, 其他的@Component,入门级别的小白已经根据视频跑起来项目, 也能根据例子进行增删改查的操作, 可是总有些疑问, 我们不都是用new 创建一个实例对象, 然后使用他们的方法和属性,但springboot里有了 @Autowired就行了,

hanker的博客 916

SpringBoot:@Component, @Service, @Repository, @Controller, @Bean使用说明

@Component, @Service, @Repository, @Controller, @Bean使用说明

netyeaxi的专栏 1729

Spring Boot 注解探秘:Bean 管理的艺术

在 Spring Boot 应用开发中,Bean 的管理是核心功能之一。Spring Boot 提供了一套强大的注解系统,帮助开发者轻松管理 Bean 的生命周期和依赖注入。本文将深入探讨 Spring Boot 中常用的 Bean 处理注解及其应用场景。

weixin_45593273的博客 1572

【Spring】基于注解的Spring容器配置—— @Component及其衍生注解

通过使用@Component及其衍生注解,Spring框架为我们提供了一种简洁、灵活的方式来管理应用程序的组件。这种基于注解的配置方式使得代码更易于理解和维护,特别是在大型项目中。减少配置文件:减少了XML配置文件的复杂性,代码更加简洁。提高可读性:注解使得代码结构更加清晰,便于理解。增强可维护性:代码的模块化使得各个组件之间的依赖关系更加明确,便于后期维护和扩展。通过本次讲解,希望能够帮助你深入理解Spring中的注解配置及其重要性,合理使用这些注解将极大地提高开发效率和代码质量。

thinking_chou的专栏 1118

@controller,@service,@repository,@component区别

原文地址:https://blog.youkuaiyun.com/weixin_37848710/article/details/79609130 1、@controller 控制器(注入服务) 用于标注控制层,相当于struts中的action层 2、@service 服务(注入dao) 用于标注服务层,主要用来进行业务的逻辑处理 3、@repository(实现dao访问) 用于标注数据访问层,也可以说用于标注数据访问组件,即DAO组件. 4、@component (把普通pojo实例化到spring容

abberr的博客 2298
上一篇: python 字典(Dictionary) vs. 集合(Set):它们是如何做到快速查找的?为什么字典的键(key)必须是不可变的?
下一篇: Starter 的魔力: 为什么我只是在 pom.xml 中加入了 spring-boot-starter-web,就能直接注入 TomcatWebServer 等复杂的对象?
冰糖心书房
博客等级 码龄15年 6014粉丝 690原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值