Spring bean 的生命周期、注入方式和作用域

news2025/5/18 3:17:28

一、Spring Bean的生命周期

Spring Bean的生命周期是指从Bean的定义加载到最终销毁的整个过程,Spring框架在每个阶段都提供了钩子方法,允许开发者在特定时机执行自定义逻辑。

1. Bean定义加载阶段

容器启动时加载配置(XML/注解/JavaConfig),解析@Component、@Bean等注解或XML配置,生成BeanDefinition。BeanDefinition是描述Bean的元数据对象,包含类名、作用域、初始化方法、属性值、依赖关系等信息。

2. Bean实例化阶段

Spring容器根据BeanDefinition创建Bean实例,通常通过反射机制实现。例如,对于UserService类,Spring会使用类似Class.forName("com.example.UserService").newInstance()的方式创建对象实例。

3. 属性填充阶段

在实例化之后,Spring会将依赖的其他Bean注入到当前Bean中。例如,如果UserService依赖于UserRepository,Spring会查找并将UserRepository的实例注入到UserService中。

4. 初始化回调阶段

Bean可以实现InitializingBean接口,在afterPropertiesSet方法中编写初始化逻辑。也可以通过以下方式实现初始化回调:

public class ExampleBean implements InitializingBean {
    public void afterPropertiesSet() {
        // 初始化逻辑
    }
}

或使用@PostConstruct注解标记初始化方法420。

5. 销毁阶段

在容器关闭时,Spring会调用实现了DisposableBean接口的Bean的destroy()方法,或使用@PreDestroy注解标记的方法执行清理工作。

二、Spring Bean的注入方式

Spring支持多种依赖注入方式,每种方式有其适用场景和优缺点。

1. 构造器注入(Constructor Injection)

通过类的构造函数注入依赖,是Spring官方推荐的方式,尤其是在Spring 4.3及以上版本中。

特点:

  • 不可变性:依赖项在对象创建时注入,之后不可更改
  • 强依赖:明确表示类的依赖关系
  • 易于测试:便于单元测试
  • 避免循环依赖:如果存在循环依赖,Spring会抛出异常

示例代码:

@Service
public class UserService {
    private final UserRepository userRepository;
    
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

2. Setter注入(Setter Injection)

通过setter方法注入依赖,适用于可选依赖或需要在对象创建后进行依赖设置的情况。

特点:

  • 灵活性高:支持可选依赖
  • 解决循环依赖:Spring容器可处理Setter注入的循环依赖
  • 向后兼容:适合逐步迁移旧代码到依赖注入模式

示例代码:

@Service
public class OrderService {
    private PaymentProcessor paymentProcessor;
    
    @Autowired
    public void setPaymentProcessor(PaymentProcessor paymentProcessor) {
        this.paymentProcessor = paymentProcessor;
    }
}

3. 字段注入(Field Injection)

直接在类的字段上使用注解注入依赖,虽然代码简洁但不被推荐。

特点:

  • 代码简洁
  • 可能导致循环依赖
  • 不利于单元测试
  • 无法使用final修饰符

4. 方法注入(Method Injection)

一种特殊的注入方式,主要用于解决单例Bean中需要原型Bean的情况。

实现方式:

  • 实现ApplicationContextAware接口,手动获取Bean
  • 使用@Lookup注解标记方法

示例代码:

@Component
public class CommandManager implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    
    public Object process(Map<String, Object> params) {
        Command command = createCommand();
        command.setStateMap(params);
        return command.execute();
    }
    
    protected Command createCommand() {
        return applicationContext.getBean(Command.class);
    }
}

三、Spring Bean的作用域

Spring Bean的作用域决定了Bean实例的创建方式和生命周期管理。

1. 标准作用域

作用域描述适用场景
singleton整个容器中只有一个实例无状态Bean,Spring默认作用域
prototype每次请求都创建新实例有状态Bean

2. Web相关作用域

作用域描述适用场景
request每个HTTP请求创建一个新实例Web请求处理
session每个用户会话创建一个实例用户会话数据
applicationServletContext生命周期全局应用数据

3. 自定义作用域

Spring允许开发者创建自定义作用域,例如线程级作用域或多租户系统中的租户级作用域22。

实现步骤:

  1. 实现Scope接口
  2. 注册自定义作用域到容器
  3. 在Bean定义中使用自定义作用域

4. 作用域与生命周期的关系

不同作用域的Bean在生命周期管理上有显著差异:

  • singleton Bean‌:在容器启动时创建,容器关闭时销毁
  • prototype Bean‌:每次请求时创建,由调用者负责销毁
  • request/session Bean‌:在请求/会话开始时创建,在请求/会话结束时销毁

四、最佳实践与最新特性(2025)

1. 注入方式选择

  • 强制依赖‌:优先使用构造器注入
  • 可选依赖‌:考虑使用Setter注入
  • 避免使用‌:字段注入,特别是在新项目中

2. 生命周期管理

  • 使用@PostConstruct@PreDestroy注解管理初始化和销毁逻辑,而不是实现InitializingBeanDisposableBean接口
  • 对于持有外部资源(如数据库连接)的Bean,务必实现销毁逻辑

3. 作用域选择

  • 默认使用singleton作用域
  • 有状态对象使用prototype作用域
  • Web相关数据使用request/session作用域

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

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

相关文章

Python 之类型注解

类型注解允许开发者显式地声明变量、函数参数和返回值的类型。但是加不加注解对于程序的运行没任何影响&#xff08;是非强制的&#xff0c;且类型注解不影响运行时行为&#xff09;&#xff0c;属于 有了挺好&#xff0c;没有也行。但是大型项目按照规范添加注解的话&#xff…

【linux】Web服务—搭建nginx+ssl的加密认证web服务器

准备工作 步骤&#xff1a; 一、 新建存储网站数据文件的目录 二、创建一个该目录下的默认页面&#xff0c;index.html 三、使用算法进行加密 四、制作证书 五、编辑配置文件&#xff0c;可以选择修改主配置文件&#xff0c;但是不建议 原因如下&#xff1a; 自定义一个配置文…

基于HTTP头部字段的SQL注入:SQLi-labs第17-20关

前置知识&#xff1a;HTTP头部介绍 HTTP&#xff08;超文本传输协议&#xff09;头部&#xff08;Headers&#xff09;是客户端和服务器在通信时传递的元数据&#xff0c;用于控制请求和响应的行为、传递附加信息或定义内容类型等。它们分为请求头&#xff08;Request Headers&…

实战解析MCP-使用本地的Qwen-2.5模型-AI协议的未来?

文章目录 目录 文章目录 前言 一、MCP是什么&#xff1f; 1.1MCP定义 1.2工作原理 二、为什么要MCP&#xff1f; 2.1 打破碎片化的困局 2.2 实时双向通信&#xff0c;提升交互效率 2.3 提高安全性与数据隐私保护 三、MCP 与 LangChain 的区别 3.1 目标定位不同 3.…

RabbitMQ高级篇-MQ的可靠性

目录 MQ的可靠性 1.如何设置数据持久化 1.1.交换机持久化 1.2.队列持久化 1.3.消息持久化 2.消息持久化 队列持久化&#xff1a; 消息持久化&#xff1a; 3.非消息持久化 非持久化队列&#xff1a; 非持久化消息&#xff1a; 4.消息的存储机制 4.1持久化消息&…

fpga系列 HDL : Microchip FPGA开发软件 Libero Soc 项目仿真示例

新建项目 项目初始界面中创建或导入设计文件&#xff1a; 新建HDL文件 module test (input [3:0] a,input [3:0] b,output reg [3:0] sum,output reg carry_out );always (*) begin{carry_out, sum} a b; endendmodule点击此按钮可进行项目信息的重新…

DeepSearch:WebThinker开启AI搜索研究新纪元!

1&#xff0c;项目简介 WebThinker 是一个深度研究智能体&#xff0c;使 LRMs 能够在推理过程中自主搜索网络、导航网页&#xff0c;并撰写研究报告。这种技术的目标是革命性的&#xff1a;让用户通过简单的查询就能在互联网的海量信息中进行深度搜索、挖掘和整合&#xff0c;从…

springCloud/Alibaba常用中间件之Setinel实现熔断降级

文章目录 SpringCloud Alibaba:依赖版本补充Sentinel:1、下载-运行&#xff1a;Sentinel(1.8.6)下载sentinel&#xff1a;运行&#xff1a;Sentinel <br> 2、流控规则① 公共的测试代码以及需要使用的测试Jmeter①、流控模式1. 直接:2. 并联:3. 链路: ②、流控效果1. 快速…

Deeper and Wider Siamese Networks for Real-Time Visual Tracking

现象&#xff1a; the backbone networks used in Siamese trackers are relatively shallow, such as AlexNet , which does not fully take advantage of the capability of modern deep neural networks. direct replacement of backbones with existing powerful archite…

黑马程序员C++2024版笔记 第0章 C++入门

1.C代码的基础结构 以hello_world代码为例&#xff1a; 预处理指令 #include<iostream> using namespace std; 代码前2行是预处理指令&#xff0c;即代码编译前的准备工作。&#xff08;编译是将源代码转化为可执行程序.exe文件的过程&#xff09; 主函数 主函数是…

foxmail - foxmail 启用超大附件提示密码与帐号不匹配

foxmail 启用超大附件提示密码与帐号不匹配 问题描述 在 foxmail 客户端中&#xff0c;启用超大附件功能&#xff0c;输入了正确的账号&#xff08;邮箱&#xff09;与密码&#xff0c;但是提示密码与帐号不匹配 处理策略 找到 foxmail 客户端目录/Global 目录下的 domain.i…

Crowdfund Insider聚焦:CertiK联创顾荣辉解析Web3.0创新与安全平衡之术

近日&#xff0c;权威金融科技媒体Crowdfund Insider发布报道&#xff0c;聚焦CertiK联合创始人兼CEO顾荣辉教授在Unchained Summit的主题演讲。报道指出&#xff0c;顾教授的观点揭示了Web3.0生态当前面临的挑战&#xff0c;以及合规与技术在推动行业可持续发展中的关键作用。…

PowerBI链接EXCEL实现自动化报表

PowerBI链接EXCEL实现自动化报表 曾经我将工作中一天的工作缩短至2个小时&#xff0c;其中最关键的一步就是使用PowerBI链接Excel做成一个自动化报表&#xff0c;PowerBI更新源数据&#xff0c;Excel更新报表并且保留报表格式。 以制作一个超市销售报表为例&#xff0c;简单叙…

腾讯云MCP数据智能处理:简化数据探索与分析的全流程指南

引言 在当今数据驱动的商业环境中&#xff0c;企业面临着海量数据处理和分析的挑战。腾讯云MCP(Managed Cloud Platform)提供的数据智能处理解决方案&#xff0c;为数据科学家和分析师提供了强大的工具集&#xff0c;能够显著简化数据探索、分析流程&#xff0c;并增强数据科学…

Android framework 中间件开发(一)

在Android开发中,经常会调用到一些系统服务,这些系统服务简化了上层应用的开发,这便是中间件的作用,中间件是介于系统和应用之间的桥梁,将复杂的底层逻辑进行一层封装,供上层APP直接调用,或者将一些APP没有权限一些操作放到中间件里面来实施. 假设一个需求,通过中间件调节系统亮…

MATLAB中的概率分布生成:从理论到实践

MATLAB中的概率分布生成&#xff1a;从理论到实践 引言 MATLAB作为一款强大的科学计算软件&#xff0c;在统计分析、数据模拟和概率建模方面提供了丰富的功能。本文将介绍如何使用MATLAB生成各种常见的概率分布&#xff0c;包括均匀分布、正态分布、泊松分布等&#xff0c;并…

C# 面向对象 构造函数带参无参细节解析

继承类构造时会先调用基类构造函数&#xff0c;不显式调用基类构造函数时&#xff0c;默认调用基类无参构造函数&#xff0c;但如果基类没有写无参构造函数&#xff0c;会无法调用从而报错&#xff1b;此时&#xff0c;要么显式的调用基类构造函数&#xff0c;并按其格式带上参…

在 C# 中将 DataGridView 数据导出为 CSV

在此代码示例中&#xff0c;我们将学习如何使用 C# 代码将 DataGridView 数据导出到 CSV 文件并将其保存在文件夹中。 在这个程序中&#xff0c;首先&#xff0c;我们必须连接到数据库并从中获取数据。然后&#xff0c;我们将在数据网格视图中显示该数据&#xff0c;…

MySQL中表的增删改查(CRUD)

一.在表中增加数据&#xff08;Create&#xff09; INSERT [INTO] TB_NAME [(COLUMN1,COLUMN2,...)] VALUES (value_list1),(value_list2),...;into可以省略可仅选择部分列选择插入&#xff0c;column即选择的列&#xff0c; 如图例可以选择仅在valuelist中插入age和id如果不指…

项目思维vs产品思维

大家好&#xff0c;我是大明同学。 这期内容&#xff0c;我们来聊一下项目思维和产品思维的区别。 项目是实施关键&#xff0c;力求每一步都精准到位&#xff1b;产品则是战略导向&#xff0c;确保所选之路正确无误。若缺乏优异成果&#xff0c;即便按时完成&#xff0c;也只…