news 2026/4/2 6:19:56

【SpringBoot】Spring IOC DI 五大注解 Bean 扫描路径 依赖注入

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【SpringBoot】Spring IOC DI 五大注解 Bean 扫描路径 依赖注入

文章目录

  • Ⅰ. 什么是 `IOC` 和 `DI`❓❓❓
  • Ⅱ. 五大注解
  • Ⅲ. 注解 `@Bean`
  • Ⅳ. 扫描路径 `@ComponentScan`
  • Ⅴ. 依赖注入
    • 一、三种注入方式 `@Autowired`
      • ① 属性注入
      • ② 构造方法注入
      • ③ `Setter`方法注入
      • 三种注入方式的区别
    • 二、`@Autowired` 存在的问题
      • ① `@Primary`
      • ② `@Qualifier`
      • ③ `@Resource`⭐⭐⭐

Ⅰ. 什么是IOCDI❓❓❓

IOC全称是Inversion of Control,中文叫 “控制反转”。

简单的说,就是把对象的创建和依赖关系的维护交给框架管理,而不是自己在代码中new出来

IOC是一种设计思想而注解DI是实现IOC的方式之一

IOC的好处如下所示:

优点说明
解耦组件之间不直接 new,依赖由框架注入
易测试方便用 mock 对象进行单元测试
灵活替换想换实现类,只改配置或注解,不改业务代码
更清晰的架构各层职责分明,依赖关系可视化

此外,Spring容器管理的对象,称为Bean对象。

@Component@AutowiredSpring框架中非常核心的两个注解,是实现IOC(控制反转)DI(依赖注入)的关键工具。

  • @Component:一个类级注解,用于将普通的Java类声明为Spring管理的Bean
  • @Autowired:一个非类级注解,用于自动注入依赖对象,而无需手动new

如何从Spring容器中获取对象❓❓❓

可以从ApplicationContext中的getBean()方法获取,如下所示:

publicstaticvoidmain(String[]args){// 在启动类中拿到ApplicationContext对象ApplicationContextcontext=SpringApplication.run(Application.class,args);// 第一种传参方式UserComponentbean1=context.getBean(UserComponent.class);bean1.func();// 第二种传参方式(需要强转)UserConfigbean2=(UserConfig)context.getBean("userConfig");bean2.func();}

getBean()方法,实际上是ApplicationContext实现了BeanFactory接口得到的,并且在其基础上添加了对国际化支持、资源访问支持、以及事件传播等方面的支持! 此外,getBean()对于Bean的名称约定如下所示:

  • 以小写字母开头,然后使用小驼峰的格式。如类名为:UserController,则Bean名为:userController
  • 特殊情况:当第一个和第二个字母为大写时,则保留原始的大小写。如类名为:UController,则Bean名为UController

Ⅱ. 五大注解

注解作用常见使用位置
@Component通用组件,标识该类为Bean工具类、业务组件
@Controller控制层,接收前端请求MVC控制器类
@Service业务逻辑层Service
@Repository数据持久层DAO类,MyBatis Mapper
@Configuration配置类用于代替XML配置

常见的目录结构规范如下所示:

src └── main └── java └── com.example.project ├── controller # 控制器层(@Controller/@RestController) ├── service # 业务逻辑层(@Service) ├── dao/mapper # 数据访问层(@Repository/@Mapper) ├── model/entity # 实体类(POJO/DTO/DO/VO) └── config # 配置类(@Configuration)

注意:五大注解均可以起别名!

Ⅲ. 注解@Bean

@Bean告诉spring这个方法返回的对象要放进IoC容器(ApplicationContext)里,成为可被任何其他Bean注入的组件

💥注意事项:

  1. @Bean要配合五大注解使用,不能单独使用

  2. Spring中,默认情况下Bean的作用域是singleton(单例)的,即整个Spring容器中只存在一个该Bean实例

  3. 对于同一个类,要定义多个Bean对象的话,需要对不同的方法进行注解,然后使用ApplicationContext对象的getBean()方法中传入Bean名称的方式进行获取,对应的Bean名称是对应方法的名称,当然也可以进行重命名,默认重命名的属性是name,如下所示

    @ComponentpublicclassUserComponent{@Bean("{u3}")publicUseru1(){returnnewUser();}@BeanpublicUseru2(){returnnewUser();}}publicstaticvoidmain(String[]args){ApplicationContextcontext=SpringApplication.run(Application.class,args);// 通过 Bean 名获取,不然 Spring 会报错,识别不出要哪个对象// 并且可以对 Bean 对象进行重命名!Useru1=(User)context.getBean("u3");Useru2=(User)context.getBean("u2");System.out.println(u1);System.out.println(u2);}// 运行结果:com.liren.ioc.model.User@abbe000com.liren.ioc.model.User@3f81621c

Ⅳ. 扫描路径@ComponentScan

Spring默认扫描的范围是SpringBoot启动类所在包及其子包,如下图所示,一般也推荐直接把启动类放到项目目录中!

但是如果需要放在特定包内,还需要访问其它非子包的包内,则需要使用@ComponentScan来添加要扫描的包,如下所示,当然也可以{}配置多个包路径

@ComponentScan("com.liren.ioc.service")// 指定扫描com.liren.ioc.service包中的内容@SpringBootApplicationpublicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);}}

Ⅴ. 依赖注入

一、三种注入方式@Autowired

① 属性注入

这种方式虽然不是官方最推荐的,但却是日常开发最常用的。

@ControllerpublicclassUserController{@AutowiredprivateUserServiceuserService;publicvoidfunc(){System.out.println("UserController");userService.func();}}

② 构造方法注入

💥注意:如果类只有一个构造方法,那么@Autowired注解可以省略;如果类中有多个构造方法,那么需要添加上@Autowired来明确指定到底使用哪个构造方法。

@ControllerpublicclassUserController{privateUserServiceuserService;// 默认构造方法publicUserController(){}// 如果有默认构造方法,那么不显式写上@Autowired的话,会去调用默认构造方法@AutowiredpublicUserController(UserServiceuserService){this.userService=userService;}publicvoidfunc(){System.out.println("UserController");userService.func();}}

Setter方法注入

@ControllerpublicclassUserController{privateUserServiceuserService;@AutowiredpublicvoidsetUserService(UserServiceuserService){this.userService=userService;}publicvoidfunc(){System.out.println("UserController");userService.func();}}

三种注入方式的区别

  1. 属性注入
    1. 优点:简洁,使用方便
    2. 缺点:
      1. 只能用于IOC容器,如果是非IOC容器不可用,并且只有在使用的时候才会出现空指针异常
      2. 不能注入一个Final修饰的属性
  2. 构造函数注入(Spring 4.X 推荐)
    1. 优点:
      • 可以注入final修饰的属性
      • 注入的对象不会被修改
      • 依赖对象在使用前一定会被完全初始化,因为依赖是在类的构造方法中执行的,而构造方法是在类加载阶段就会执行的方法。
      • 通用性好,构造方法是JDK支持的,所以更换任何框架,它都是适用的
    2. 缺点:
      • 注入多个对象时,代码会比较繁琐
  3. Setter 注入(Spring 3.X 推荐)
    1. 优点:方便在类实例之后,重新对该对象进行配置或者注入
    2. 缺点:
      • 不能注入一个final修饰的属性
      • 注入对象可能会被改变,因为setter方法可能会被多次调用,就有被修改的风险

二、@Autowired存在的问题

当同一个类存在多个Bean时,使用@Autowired会存在问题,如下所示:

如何解决上述问题呢❓❓❓Spring提供了以下几种解决方案:

  • @Primary
  • @Qualifier
  • @Resource

@Primary

当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现!

这个注解加在要被指定注入的Bean对象上,如下所示:

@ComponentpublicclassUserComponent{@Primary@BeanpublicUseru3(){returnnewUser();}@BeanpublicUseru4(){returnnewUser();}}

@Qualifier

注意该注解不能单独使用,需要配合@Autowired才行

@ControllerpublicclassUserController2{@Qualifier("u3")// 指定对应Bean的名称@AutowiredprivateUseruser;publicvoidfunc(){System.out.println("UserController2");}}

@Resource⭐⭐⭐

该注解可以单独使用,不过需要显式用属性name来指定对应的Bean对象!

@ControllerpublicclassUserController2{@Resource(name="u3")// 需要显式写一下name来指定privateUseruser;publicvoidfunc(){System.out.println("UserController2");}}

需要注意的是,@ResourceJDK自带的,支持更多的参数设置,而@AutowiredSpring框架提供的,没有前者功能那么多!

@Autowired的装配顺序如下图所示:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/1 14:32:46

【干货收藏】手把手教你申请软件著作权,一篇搞定全流程!

还在为申请软著头疼?别急!这份超详细攻略带你轻松走完所有流程,从注册到拿证,一步都不少!第一步:注册与实名 先登录「中国版权保护中心」官网,注册账号并完成实名认证,这是申请的第一…

作者头像 李华
网站建设 2026/3/26 23:35:50

FaceFusion支持三维人脸建模输出吗?OBJ格式导出测试

FaceFusion支持三维人脸建模输出吗?OBJ格式导出测试 在数字内容创作日益智能化的今天,AI驱动的人脸处理工具正以前所未有的速度重塑影视、游戏和虚拟现实的工作流程。FaceFusion作为当前开源社区中最具影响力的人脸交换项目之一,凭借其高保真…

作者头像 李华
网站建设 2026/3/26 23:35:48

告别PPT焦虑:百考通AI如何用智能模板重塑学术演示体验

在学术研究的漫长征途上,从开题报告的初次亮相到毕业答辩的终极考验,一份逻辑清晰、设计专业的PPT往往是研究者展示成果、传递思想的关键载体。然而,现实情况是,许多研究生和职场新人将大量宝贵时间耗费在了模板搜寻、格式调整与内…

作者头像 李华
网站建设 2026/3/31 13:13:53

告别“闭门造车”,AI智能问卷设计,百考通助你精准捕捉用户心声!

在市场调研、用户研究、学术调查乃至内部管理中,一份设计精良的问卷是获取真实、有效数据的基石。然而,设计一份既能精准触达核心问题,又能引导受访者顺畅作答,还能确保数据可分析、有价值的问卷,却是一项极具挑战性的…

作者头像 李华
网站建设 2026/3/27 12:53:26

3步掌握Flowblade:Linux上最顺手的开源视频剪辑工具

3步掌握Flowblade:Linux上最顺手的开源视频剪辑工具 【免费下载链接】flowblade Video Editor for Linux 项目地址: https://gitcode.com/gh_mirrors/fl/flowblade 如果你正在寻找一款功能强大又易于上手的Linux视频编辑软件,那么Flowblade绝对值…

作者头像 李华
网站建设 2026/3/27 9:34:54

Android11 新特性与适配指南

Android 11(API 30)引入了多项重要特性和权限变更,核心集中在存储权限、后台位置、包可见性、前台服务 等方面。本文基于 Kotlin 语言,从核心变更点、适配方案、代码示例等维度讲解适配要点。 一、核心变更概览 变更类别核心影响…

作者头像 李华