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 严禁定义可变成员变量,避免并发数据问题。

相关推荐
炸薯条!6 小时前
二叉树的链式表示(2)
java·数据结构·算法
小闹5496 小时前
CLAUDE CODE生成可视化数据库工具
后端
徐寿春6 小时前
什么是数据倾斜
java·guava
李白的天不白6 小时前
一个服务器可以搭建多个网站
java·tomcat
●VON6 小时前
AtomGit Flutter鸿蒙客户端:共享组件
java·flutter·华为·harmonyos·鸿蒙
程序猿乐锅6 小时前
【JAVASE | 第十七篇】Java 网络通信
java·开发语言
执于代码7 小时前
Java交互打印的问题
java
星星电灯猴7 小时前
全面解决Charles抓取HTTPS请求响应中文乱码问题的方法与技巧
后端·ios
我命由我123457 小时前
Windows 操作系统 - Windows 查看防火墙是否开启、Windows 查看防火墙放行端口
java·运维·开发语言·windows·java-ee·操作系统·运维开发
fly spider7 小时前
Spring 原理总览:从启动到请求执行
java·数据库·spring