Spring Bean 作用域与生命周期

一、Spring Bean 作用域

Bean 作用域用于控制 Bean 实例的创建规则、数量及存活范围,Spring 官方提供 5 种核心作用域,默认作用域为 singleton(单例)

1. singleton(单例,默认)

整个 Spring IoC 容器中仅会创建一个 Bean 实例,全局所有调用、注入场景都会复用该实例,Bean 的创建与销毁均由 Spring 容器统一管理。

核心注意点 :单例 Bean 非线程安全,多线程并发场景下,禁止在 Bean 中定义成员变量存储业务数据,避免数据错乱问题。

适用场景:无状态业务 Bean,如 Service、Dao、工具类、配置类等。

2. prototype(原型)

每次通过容器获取 Bean、依赖注入 Bean 时,都会创建一个全新的实例。与单例模式最大的区别是,Spring 容器只负责创建原型 Bean,不管理其销毁,资源释放需要开发者手动处理。

适用场景:有状态、需要独立实例的业务场景,多线程专属 Bean。

3. request(请求作用域)

仅适用于 Web 开发环境。每一次 HTTP 请求都会创建一个全新的 Bean,请求处理结束后,该 Bean 会自动销毁。

4. session(会话作用域)

仅适用于 Web 开发环境。对应单个用户的浏览器会话,同一个用户的多次请求共享一个 Bean,当用户会话超时、主动退出或关闭页面时,Bean 随之销毁。

适用场景:存储用户登录信息、临时购物车数据等用户专属数据。

5. application(应用作用域)

仅适用于 Web 开发环境。整个 Web 应用生命周期内只存在一个 Bean,作用域范围等同于 ServletContext,项目启动创建、项目关闭销毁,属于全局共享 Bean。

二、Spring Bean 完整生命周期

Spring Bean 的生命周期是指 Bean 从创建、初始化、投入使用,到最终销毁的完整流程,核心可概括为 五大核心阶段,初始化和销毁阶段有固定的方法执行优先级,是面试核心考点。

1. 实例化

Spring 容器扫描到 Bean 定义后,通过反射调用 Bean 的构造方法,在堆内存中创建空对象,此时对象仅完成初始化,尚未赋值、无依赖关系。

2. 属性注入(依赖填充)

容器自动完成依赖装配,通过 @Autowired、@Value 或配置文件,为实例化后的 Bean 填充属性、注入依赖对象,建立 Bean 之间的关联关系。

3. 初始化(固定执行顺序)

属性赋值完成后,执行 Bean 的初始化方法,优先级从高到低固定如下:

  1. @PostConstruct 注解方法
  2. InitializingBean 接口 afterPropertiesSet() 方法
  3. 自定义 init-method 初始化方法

4. 运行使用阶段

初始化完成的 Bean 存入 Spring 容器缓存,正式对外提供服务,响应业务调用、处理业务逻辑。

5. 销毁(容器关闭时执行)

当 Spring 容器关闭、项目停止时,执行 Bean 的销毁方法,优先级从高到低固定如下:

  1. @PreDestroy 注解方法
  2. DisposableBean 接口 destroy() 方法
  3. 自定义 destroy-method 销毁方法

三、面试极简口述总结

  1. 作用域:Spring Bean 默认是 singleton 单例,容器全局唯一、统一管理生命周期;prototype 每次获取都会新建实例,容器不负责销毁;request、session、application 仅在 Web 环境生效,分别对应单次请求、单个用户会话、全局应用。同时单例 Bean 存在线程安全问题,不建议存储可变成员变量。

  2. 生命周期:整体流程为 实例化 → 属性注入 → 初始化 → 运行使用 → 销毁。初始化优先级:注解 > 接口 > 自定义方法;销毁优先级同样遵循注解优先、接口次之、自定义方法最后的规则。

四、核心面试易错点

  1. Spring 单例是容器级单例,并非 JVM 全局单例;

  2. prototype 原型 Bean 容器不管理销毁,需手动释放资源;

  3. 初始化、销毁方法执行顺序固定,是面试高频提问点;

  4. 单例 Bean 严禁定义可变成员变量,避免并发数据问题。

相关推荐
Larcher4 小时前
React Router 不只是页面跳转:从 SPA 路由到权限守卫的完整实践
javascript·后端
Larcher4 小时前
大模型为什么每次回答都不一样?一文搞懂 Temperature、Top K 与 Top P
javascript·后端
LucianaiB6 小时前
毕业老学长给我留的最后一句话是:“AI 写的,别挂我名。” 我直接 神(Seed Evolving) 来!助我!
后端
IvanCodes6 小时前
RAG 实战教程(一):RAG 工作原理与完整流程——分片、索引、召回、重排和生成
人工智能·后端·agent
·薯条大王7 小时前
经济实惠玩云服务器|一台云服务器多人共用,子账号配置教程
java·linux·运维·服务器·汇编·c++·python
CodeSheep7 小时前
稚晖君公司人事大变动,来了!
前端·后端·程序员
小满zs7 小时前
Go语言第八章(函数)
后端·go
stark张宇9 小时前
实战Go高级特性:Context超时控制、defer资源回收与Channel通信的关键避坑点
后端·go
ZJH__GO10 小时前
网络编程v4pro--实现聊天室文件传输功能
java·服务器·网络·计算机网络
程序员黑豆10 小时前
Windows 系统 Java 环境变量配置全攻略:解决“不是内部或外部命令”
java·前端·ai编程