当前位置: 首页 > news >正文

Spring Bean作用域以及生命周期

前言

在之前已经有几篇文章来讲解过Bean的创建和依赖注入等相关内容,这篇文章补充一下关于Bean的一些重要内容:Bean作用域和生命周期

一、Bean作用域

1.定义

作用域 = Spring 容器创建 Bean 的「实例数量」和「存活范围」

它决定了:

  • 整个项目有几个这个 Bean 对象?

  • 什么时候创建?

  • 什么时候销毁?

  • 是否线程共享?

2.分类

Spring 6主流提供六种内置作用域,日常开发常用前四种

  • singleton(单例,默认)
  • prototype(多例)
  • request(请求域)
  • session(会话域)
  • application(应用域)
  • websocket(长连接域)

二、六大作用域详解

配置指定作用域使用注解@Scope

1.singleton 单例(默认作用域)

  • 规则:整个 Spring IoC 容器中仅存在一个 Bean 实例,全局共享。
  • 创建时机
    • 默认:容器启动时立即初始化(饿汉式)
    • 配合lazy-init="true":第一次获取 Bean 时才创建(懒加载)
  • 销毁时机:IoC 容器关闭时销毁。
  • 使用场景:无状态 Bean(Service、Mapper、Controller、工具类),绝大多数业务组件。
  • 注意:单例 Bean 非线程安全。如果 Bean 中有成员变量,多线程并发修改会出现数据错乱。
  • 配置注解:
@Component // 可省略,默认就是 singleton @Scope("singleton") public class UserService { }

2.prototype 多例

  • 规则每次从容器获取 Bean,都会创建全新实例,容器只负责创建,不管理生命周期。
  • 创建时机每次getBean()/ 依赖注入时创建
  • 销毁时机:Spring 容器不负责销毁,由 JVM GC 回收。
  • 使用场景:有状态 Bean、实体对象、请求级临时对象、非共享实例。
  • 易错点:单例 Bean(Service/Controller)中注入多例 Bean,多例会失效。因为单例仅启动时注入一次依赖,后续不会刷新。
  • 解决方案:通过ApplicationContext手动获取、使用ObjectProvider
  • 配置注解:
@Component @Scope("prototype") public class Order { }

3.request 请求域(Web 环境专属)

  • 核心规则:每一次 HTTP 请求,都会创建一个全新的 Bean 实例;请求处理完毕,Bean 立即销毁
  • 生命周期:跟随 HTTP 请求,最短、最临时的 Web 作用域。
  • 使用场景:存储单次请求专属临时数据、请求上下文、请求参数封装、单次请求日志追踪信息。
  • 注解配置
@Component @Scope("request") public class RequestContext { // 存储本次请求的请求ID、客户端IP、请求时间等临时数据 private String requestId; private String clientIp; }

4.session 会话域(Web 环境专属)

  • 核心规则:同一个用户浏览器 Session 会话,对应唯一一个 Bean 实例;会话过期、浏览器关闭、Session 失效,Bean 自动销毁
  • 生命周期:跟随用户会话,贯穿用户多次接口请求。
  • 使用场景:存储用户会话级数据,如登录用户信息、临时会话缓存、权限临时标识、用户行为记录。
  • 底层特点:Bean 绑定HttpSession,不同用户会话数据完全隔离。

  • 注解配置

@Component @Scope("session") public class UserSessionInfo { // 存储当前登录用户信息,单用户会话共享 private Long userId; private String username; private String token; }

5.application 应用域(Web 环境专属)

  • 核心规则:整个 Web 应用全局仅存在一个 Bean 实例,生命周期与ServletContext完全一致。
  • 关键区别(高频面试)
  • singleton:仅单个 Spring IoC 容器内单例

  • application:整个 Web 应用、跨 Spring 容器全局单例,作用域范围更大

  • 使用场景:存储项目全局公共数据、系统配置、全局统计数据、公共常量缓存。
  • 销毁时机:项目停止、Web容器销毁时统一释放
  • 注解配置
@Component @Scope("application") public class SystemGlobalConfig { // 项目全局配置,全应用共享 private String projectName; private Integer maxUploadSize; }

6.websocket 长连接域(Web 环境专属)

  • 核心规则:每一条 WebSocket 长连接,对应一个独立 Bean 实例;连接断开、客户端下线,Bean 立即销毁
  • 使用场景:即时通讯、消息推送、在线聊天室、实时数据监控、长连接状态存储。
  • 注解配置代码
@Component @Scope("websocket") public class WebSocketSessionBean { // 存储单条长连接专属信息 private String sessionId; private Long connectUserId; private LocalDateTime connectTime; }

三、Spring Bean生命周期

Spring Bean生命周期,是Spring IoC容器对Bean从创建、初始化、对外服务到最终销毁的全流程管控。整个过程核心分为实例化、属性赋值、初始化、销毁四大阶段,涵盖反射创建对象、DI依赖注入、Aware接口回调、初始化方法执行、AOP动态代理、容器销毁回收等核心底层逻辑。

1.阶段一:Bean实例化(造对象)

实例化是Bean生命周期的第一步,核心目的:通过底层机制创建Bean的原始空对象,此时对象仅被分配内存,尚未赋值、未完成初始化。

Spring 提供三种实例化方式,优先级与场景各有不同:

(1)反射构造函数实例化(最常用)

Spring 自动推断Bean的可用构造方法,通过JDK反射机制创建对象。

  • 如果Bean存在无参构造,默认优先使用无参构造实例化;

  • 如果仅有有参构造,Spring会自动触发构造器注入,完成实例化;

  • 这是日常开发中@Component、@Service等注解Bean的默认实例化方式。

(2)静态工厂实例化

通过工厂类的静态方法创建Bean对象,无需创建工厂实例,直接调用静态方法生成目标Bean,多用于框架内置工具类、静态资源Bean的创建。

(3)实例工厂实例化

需要先创建工厂Bean实例,再通过工厂实例的普通方法创建目标Bean,灵活性更高,可根据工厂实例的状态动态生成不同Bean对象。

2.阶段二:属性赋值(DI依赖注入)

实例化完成后,Spring进入依赖注入阶段,也是IoC容器的核心价值体现。此阶段核心目的:解析Bean的依赖关系,自动完成属性赋值,让Bean具备完整的依赖资源。

(1)四大自动装配规则

Spring默认提供四种装配模式,日常开发核心使用byType,配合@Autowired注解实现自动装配:

  • byType(按类型装配):默认主流模式,根据属性类型匹配容器中的Bean,@Autowired默认基于此实现;

  • byName(按名称装配):根据属性名与Bean的id/name匹配赋值;

  • constructor(构造器装配):通过有参构造完成依赖注入,Spring4.3后优先推荐;

  • none(不自动装配):关闭自动装配,需手动配置依赖。

(2) 核心难点:循环依赖问题

循环依赖只发生在属性赋值阶段,是此阶段最核心的底层考点。

场景:A依赖B、B依赖A,Spring在递归赋值时会产生循环引用。

Spring通过三级缓存机制,完美解决单例Bean、setter/字段注入的循环依赖问题;但无法解决多例Bean、构造器注入的循环依赖。

3.阶段三:初始化(增强与加工对象)

属性赋值完成后,Bean的依赖已经就绪,Spring开始对Bean进行自定义加工、生命周期回调、动态代理增强,是Bean从“可用对象”变成“完整业务对象”的关键阶段。整个初始化分为三步,执行顺序固定。

(1) 第一步:XXXAware接口回调(容器感知)

如果Bean实现了Spring内置的Aware感知接口,Spring会自动执行对应回调方法,让普通Bean拥有感知容器资源的能力。

常用核心Aware接口:

  • BeanNameAware:感知自身Bean名称;

  • BeanFactoryAware:感知所属Bean工厂;

  • ApplicationContextAware:感知Spring应用上下文。

未实现Aware接口的Bean,直接跳过此步骤。

(2)第二步:自定义初始化生命周期回调

Spring提供三种初始化方式,执行顺序固定、优先级不可逆,用于开发者自定义Bean初始化业务逻辑(如参数校验、资源初始化、缓存预热等):

  • @PostConstruct注解(JSR标准,优先级最高)

  • InitializingBean#afterPropertiesSet接口方法(Spring内置)

  • @Bean(initMethod = "xxx")自定义初始化方法(优先级最低)

(3)第三步:AOP动态代理创建(核心增强)

初始化收尾阶段,Spring会判断当前Bean是否需要AOP切面增强:

  • 如果Bean存在匹配的切面规则,Spring在此阶段生成动态代理对象(JDK动态代理/CGLIB代理),最终放入容器的是代理Bean;

  • 如果无需AOP增强,直接使用原始Bean对象。

4.阶段四:销毁(容器关闭回收资源)

Bean销毁是生命周期的最后一步,仅针对单例Bean(singleton)生效,多例Bean(prototype)由JVM GC回收,Spring容器不负责管理销毁。

(1)触发时机

仅在Spring IoC容器关闭时触发(项目停机、上下文close、应用销毁)。

(2)销毁生命周期回调(执行顺序固定)

与初始化逻辑对应,三种销毁方式优先级固定,用于释放资源(关闭连接、清空缓存、停止线程等):

  • @PreDestroy注解(优先级最高)

  • DisposableBean#destroy接口方法(Spring内置)

  • @Bean(destroyMethod = "xxx")自定义销毁方法(优先级最低)

5.整个过程总结

  • 实例化:反射/工厂创建原始空对象,只分配内存,无赋值无逻辑;
  • 属性赋值:完成DI自动装配,解决依赖关系,触发循环依赖处理;
  • 初始化:Aware容器感知 → 自定义初始化逻辑 → AOP动态代理增强,生成成品Bean;
  • 销毁:容器关闭时执行销毁回调,优雅释放资源(仅单例Bean生效)。
http://www.jsqmd.com/news/906048/

相关文章:

  • 2026年东莞磁环供应厂家实力评估:电源磁环、数据线磁环、充电桩磁环、工控磁环行业格局分析 - 品牌企业推荐师(官方)
  • 2026衡阳卫生间免砸砖防水、外墙、地下室、楼顶渗漏+彩钢瓦、阳光房渗漏 本地专业防水公司TOP5权威推荐(2026年6月本地最新深度调研) - 防水百科
  • 从设备树到驱动代码:在RK3566上点亮一个LED的完整实战流程(基于GPIO0_B4)
  • 深入理解Java核心:从对象比较到内存机制
  • 【YOLO目标检测全栈实战】91 知识蒸馏的工程化落地:从论文到生产环境的最后一公里
  • 13802黄大年茶思屋第138期(基础软件领域第三期)第2题:数据库内存池自适应管理技术
  • 2026昆明卫生间免砸砖防水、外墙、地下室、楼顶渗漏+彩钢瓦、阳光房渗漏 本地专业防水公司TOP5权威推荐(2026年6月本地最新深度调研) - 防水百科
  • 装配式篷房源头厂家哪家好
  • 从零实现 Python 代码审查工具:安全生命周期漏洞检测实战
  • GEO 智能营销系统落地实战与价值转化指南
  • 2026鄂州卫生间免砸砖防水、外墙、地下室、楼顶渗漏+彩钢瓦、阳光房渗漏 本地专业防水公司TOP5权威推荐(2026年6月本地最新深度调研) - 防水百科
  • 使用GD32实现JTAG功能
  • pnpm的安装和配置
  • 2026济南卫生间免砸砖防水、外墙、地下室、楼顶渗漏+彩钢瓦、阳光房渗漏 本地专业防水公司TOP5权威推荐(2026年6月本地最新深度调研) - 防水百科
  • solie实线 多段线 不显示填充
  • 20260528 2
  • 项目经理日常:我是怎么把高项十大管理47个过程,用到真实项目里的(附避坑指南)
  • 一个导出按钮,为什么最后会变成后台任务系统?
  • 2026 南京地区 GEO 服务商选择指南:五大优质机构技术与案例深度对比 - GEO优化
  • Gemini个性化推荐策略全链路拆解(从Embedding到实时重排的12个关键决策点)
  • 从Solidworks草图到桌面摆件:我如何用3D打印给自己做了个PLA手机支架(附切片避坑指南)
  • 4步搞定Ryzen系统调试:SMUDebugTool新手完全指南
  • 2026大连注册公司哪家好?优质机构top榜测评! - 小柏云
  • Windows热键冲突终极排查指南:Hotkey Detective深度解析
  • 写了8年代码,今天被95后产品经理上了一课
  • 如何用3个版本打造你自己的智能机器狗:openDogV2完整指南
  • 2026年东莞滴胶标牌/金属标牌/不锈钢标牌/铝标牌生产厂家最新概览:核心评估与实力筛选 - 品牌企业推荐师(官方)
  • 在国产中标麒麟V7.0上搞定VMware 15.5,这份保姆级避坑指南请收好
  • 告别提取码搜索困境:baidupankey如何让百度网盘资源获取变得简单
  • 华为云 ECS 主机组与云服务器组的区别?前者属于物理,后者属于虚拟