Spring boot 中的IOC容器对Bean的管理

news2025/4/25 10:47:33

Spring Boot 中 IOC 容器对 Bean 的管理,涵盖从容器启动到 Bean 的生命周期管理的全流程。


步骤 1:理解 Spring Boot 的容器启动

Spring Boot 的 IOC 容器基于 ApplicationContext,在应用启动时自动初始化。

  1. 入口类:通过 @SpringBootApplication 注解标记主类,启动容器。

    @SpringBootApplication
    public class MyApp {
        public static void main(String[] args) {
            SpringApplication.run(MyApp.class, args); // 启动容器
        }
    }
    
    • @SpringBootApplication 组合了三个核心注解:
      • @Configuration:标记为配置类。
      • @ComponentScan:自动扫描当前包及子包的组件(@Component, @Service 等)。
      • @EnableAutoConfiguration:启用 Spring Boot 的自动配置机制。
  2. 容器初始化

    • Spring Boot 启动时,创建 ApplicationContext(默认实现为 AnnotationConfigApplicationContext)。
    • 自动加载所有符合条件的 Bean(通过组件扫描和自动配置)。

步骤 2:注册 Bean 到容器

Bean 的注册主要有三种方式:

方式 1:组件扫描(自动注册)
  • 使用 @Component 及其派生注解标记类,容器自动扫描并注册为 Bean。
    @Service // 等价于 @Component,语义化标记为服务层
    public class UserService {
        // ...
    }
    
    • 其他派生注解:@Repository(DAO 层)、@Controller(Web 层)、@RestController
方式 2:Java 配置类(显式注册)
  • 定义 @Configuration 类,通过 @Bean 方法显式注册 Bean。
    @Configuration
    public class AppConfig {
        @Bean // 方法返回的对象会被注册为 Bean
        public DataSource dataSource() {
            return new HikariDataSource(); // 例如配置数据源
        }
    }
    
方式 3:自动配置(Spring Boot 特有)
  • Spring Boot 根据类路径依赖自动注册 Bean(如引入 spring-boot-starter-web 会自动配置 Tomcat、Spring MVC 相关 Bean)。
  • 原理:通过 META-INF/spring.factories 文件定义自动配置类,结合条件注解(如 @ConditionalOnClass)判断是否生效。

步骤 3:依赖注入(DI)

容器负责将依赖的 Bean 注入到需要它们的对象中。

注入方式
  1. 构造器注入(推荐)

    @Service
    public class OrderService {
        private final UserService userService;
        
        @Autowired // Spring 4.3+ 后,如果只有一个构造器,可省略 @Autowired
        public OrderService(UserService userService) {
            this.userService = userService;
        }
    }
    
  2. Setter 注入

    public class MyService {
        private MyRepository repository;
        
        @Autowired
        public void setRepository(MyRepository repository) {
            this.repository = repository;
        }
    }
    
  3. 字段注入(不推荐,仅用于简单场景)

    @Service
    public class MyService {
        @Autowired
        private MyRepository repository;
    }
    

步骤 4:Bean 的作用域管理

通过 @Scope 注解指定 Bean 的作用域。

  1. 常用作用域
    • Singleton(默认):整个容器中只有一个实例(从始至终只有这一个)。
      @Bean
      @Scope("singleton")
      public MyBean myBean() { return new MyBean(); }
      
    • Prototype:每次请求创建新实例(每次使用的时候都需要重新创建这个bean)。
      @Bean
      @Scope("prototype")
      public MyBean myBean() { return new MyBean(); }
      
    • Request(Web 环境):每个 HTTP 请求一个实例。
    • Session(Web 环境):每个用户会话一个实例。

步骤 5:Bean 的生命周期管理

通过注解或接口控制 Bean 的初始化和销毁逻辑。

  1. 初始化方法

    @Component
    public class MyBean {
        @PostConstruct // 初始化完成后执行
        public void init() {
            System.out.println("Bean 初始化完成!");
        }
    }
    
  2. 销毁方法

    @Component
    public class MyBean {
        @PreDestroy // 容器关闭前执行
        public void cleanup() {
            System.out.println("Bean 即将销毁!");
        }
    }
    

步骤 6:高级配置与条件化 Bean

通过条件注解控制 Bean 的注册。

  1. 条件注解示例

    @Configuration
    public class MyConfig {
        @Bean
        @ConditionalOnClass(name = "com.example.ExternalLibrary") // 当类路径存在该类时注册
        public MyBean myBean() {
            return new MyBean();
        }
        
        @Bean
        @ConditionalOnMissingBean // 当容器中没有该类型 Bean 时注册
        public BackupBean backupBean() {
            return new BackupBean();
        }
    }
    
  2. Profile 环境隔离

    @Bean
    @Profile("dev") // 仅在 dev 环境下激活
    public DataSource devDataSource() {
        return new EmbeddedDatabaseBuilder().build();
    }
    

步骤 7:解决常见问题

  1. 循环依赖

    • 避免构造器注入循环,改用 Setter 或字段注入。
    • 重构代码,提取公共逻辑到第三方 Bean。
  2. Bean 冲突

    • 使用 @Primary 标记首选 Bean:
      @Bean
      @Primary
      public MyService primaryService() {
          return new PrimaryService();
      }
      
    • 使用 @Qualifier 指定具体 Bean:
      @Autowired
      @Qualifier("secondaryService")
      private MyService myService;
      

步骤 8:测试与验证

  1. 集成测试

    @SpringBootTest
    class UserServiceTest {
        @Autowired
        private UserService userService; // 注入真实 Bean
    }
    
  2. 单元测试(Mock 依赖)

    @SpringBootTest
    class OrderServiceTest {
        @MockBean
        private UserService userService; // 模拟 UserService
        
        @Autowired
        private OrderService orderService;
    }
    

总结

通过以上步骤,Spring Boot 的 IOC 容器完成了以下核心任务:

  1. 启动容器:基于 @SpringBootApplicationApplicationContext
  2. 注册 Bean:通过组件扫描、配置类、自动配置。
  3. 依赖注入:构造器注入(推荐)、Setter 注入、字段注入。
  4. 作用域管理:单例、原型、请求、会话等。
  5. 生命周期控制@PostConstruct@PreDestroy
  6. 高级配置:条件化 Bean、Profile 隔离。
  7. 问题解决:循环依赖、Bean 冲突。
  8. 测试验证:集成测试与单元测试。

掌握这些步骤后,可以高效利用 Spring Boot 的 IOC 容器管理 Bean,构建松耦合、可维护的应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2342351.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt实战之将自定义插件(minGW)显示到Qt Creator列表的方法

Qt以其强大的跨平台特性和丰富的功能,成为众多开发者构建图形用户界面(GUI)应用程序的首选框架。而在Qt开发的过程中,自定义插件能够极大地拓展应用程序的功能边界,让开发者实现各种独特的、个性化的交互效果。想象一下…

【Vue】TypeScript与Vue3集成

个人主页:Guiat 归属专栏:Vue 文章目录 1. 前言2. 环境准备与基础搭建2.1. 安装 Node.js 与 npm/yarn/pnpm2.2. 创建 Vue3 TypeScript 项目2.2.1. 使用 Vue CLI2.2.2. 使用 Vite(推荐)2.2.3. 目录结构简述 3. Vue3 TS 基础语法整…

Linux之七大难命令(The Seven Difficult Commands of Linux)

Linux之七大难命令 、背景 作为Linux的初学者,肯定要先掌握高频使用的指令,这样才能让Linux的学习在短时间内事半功倍。但是,有些指令虽然功能强大,但因参数多而让初学者们很害怕,今天介绍Linux中高频使用&#xff0…

5.3.1 MvvmLight以及CommunityToolkit.Mvvm介绍

MvvmLight、CommunityToolkit.Mvvm是开源包,他们为实现 MVVM(Model-View-ViewModel)模式提供了一系列实用的特性和工具,能帮助开发者更高效地构建 WPF、UWP、MAUI 等应用程序。 本文介绍如下: 一、使用(旧)的MvvmLight库 其特点如下,要继承的基类是ViewModelBase;且使用…

Dbeaver 执行 SQL 语句和执行 SQL 脚本的区别

执行 SQL 语句 执行 SQL 语句对应图标: 适用于执行单个 SQL 的情形,默认是在光标处或选中的文本上执行 SQL 查询。 实际上同时选择多个 SQL 并通过该方式去执行也可能成功,只是有失败的风险。因此不建议使用它来同时执行多个 SQL 语句。 情况…

《Python3网络爬虫开发实战(第二版)》配套案例 spa6

Scrape | Moviehttps://spa6.scrape.center/ 请求影片列表api时,不仅有分页参数,还多了一个token,通过重发请求发现token有时间限制,所以得逆向token的生成代码。 通过xhr断点定位到接口请求位置 刷新页面或者点翻页按钮&#x…

Python基础语法:字面量,注释,关键字,标识符,变量和引用,程序执行的3大流程

目录 字面量(数据的类型) 字面量的含义 常见字面量类型(6种) 输出各类字面量(print语句) 注释(单行和多行注释) 注释的作用 单行注释和多行注释 单行注释(ctrl/&a…

SPL 量化 获取数据

下载数据 我们将股票数据分享在百度网盘上供下载,每工作日更新。 目前可供下载的数据有 A 股的日 K 线数据、股票代码列表和上市公司的基本面数据 下载链接: 百度网盘 下载数据的文件格式为 btx,是 SPL 的特有二进制格式。 btx 称为集文…

Rust 学习笔记:安装 Rust

Rust 学习笔记:安装 Rust Rust 学习笔记:安装 Rust在 Windows 上安装 Rust命令行创建 Rust 项目在 Mac/Linux 上安装 Rust一些命令升级卸载cargo -hrustc -h 安装 RustRoverrust-analyzer Rust 学习笔记:安装 Rust 在 Windows 上安装 Rust …

编译 C++ 报错“找不到 g++ 编译器”的终极解决方案(含 Windows/Linux/macOS)

前言 在使用终端编译 C 程序时,报错: 或类似提示,意味着你的系统尚未正确安装或配置 g 编译器。本篇将从零手把手教你在 Windows / Linux / macOS 下安装并配置 g,适用于新手或 C 入门阶段的你。 什么是 g? g 是 GN…

html单页业务介绍源码

源码介绍 html单页业务介绍源码,源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行 效果预览 源码免费获取 html单页业务介绍源码

单体OJ项目

单体项目版本、微服务版还需我再钻研钻研。 项目介绍 在系统前台,管理员可以创建、管理题目;用户可以自由搜索题目、阅读题目、编写并提交代码。 在系统后端,能够根据管理员设定的题目测试用例在代码沙箱 中对代码进行编译、运行、判断输出是否正确。 其…

豆包桌面版 1.47.4 可做浏览器,免安装绿色版

自己动手升级更新办法: 下载新版本后安装,把 C:\Users\用户名\AppData\Local\Doubao\Application 文件夹的文件,拷贝替换 DoubaoPortable\App\Doubao 文件夹的文件,就升级成功了。 再把安装的豆包彻底卸载就可以。 桌面版比网页版…

【MySQL】索引失效问题详解

目录 1. 最左前缀原则 2. 条件左边有函数或运算 3. 隐式类型转换 4. LIKE 模糊查询以 % 开头 5、MySQL 优化器选择全表扫描 ⭐对 in 关键字特别说明⭐ (1)列表太大时,走全表扫描了 (2)隐式类型转换 &#xff…

优选算法第十讲:字符串

优选算法第十讲:字符串 1.最长公共前缀2.最长回文子串3.二进制求和4.字符串相乘 1.最长公共前缀 2.最长回文子串 3.二进制求和 4.字符串相乘

【扣子Coze 智能体案例四】五行八卦占卜智能体

目录 一、意图识别 二、时间格式转换 三、八字转换 四、八字提取 五、八字提取2 六、数据汇总 七、统计五行占比 八、雷达图生成 九、表格生成 十、AI占卜 十一、结束节点 一、意图识别 用户输入的信息包含各种时间格式的年月日时 用户输入的信息包含天干地支八字…

5.学习笔记-SpringMVC(P61-P70)

SpringMVC-SSM整合-接口测试 (1)业务层接口使用junit接口做测试 (2)表现层用postman做接口测试 (3)事务处理— 1)在SpringConfig.java,开启注解,是事务驱动 2)配置事务管理器(因为事务管理器是要配置数据源对象&…

【专题刷题】二分查找(一):深度解刨二分思想和二分模板

📝前言说明: 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录,按专题划分每题主要记录:(1)本人解法 本人屎山代码;(2)优质解法 优质代码;&#xff…

硬核解析!电动汽车能耗预测与续驶里程的关键技术研究

引言 随着电动汽车的普及,续航里程和能耗表现成为用户关注的核心痛点。然而,表显续航与实际续航的差异、低温环境下的电量衰减等问题始终困扰着消费者。本文基于《电动汽车能耗预测与续驶里程研究》的实验成果,深入剖析电动汽车能耗预测的核心模型、多环境测试方法及续航里…

【OceanBase相关】01-OceanBase数据库部署实践

文章目录 一、前言1、介绍说明2、部署方案二、部署说明1、环境准备2、软件安装2.1、安装OAT2.2、安装OCP3、软件部署三、集群管理1、MySQL租户管理四、Q&A1、OBServer 服务器重启后 observer 进程未能自动启动1.1、问题说明1.2、解决措施2、ERROR 1235 (0A000) at line 1: …