Spring Bean 作用域 & 生命周期

Spring Bean 作用域 & 生命周期 超详细易懂笔记(零基础可学)

哈喽!这篇笔记专门整理 Spring 中 Bean 作用域Bean 生命周期 核心知识点,全程通俗易懂、无废话,适合背诵、面试复习、日常查漏补缺,零基础也能看懂。

先铺垫一句核心:Spring 容器的核心就是管理 Bean,搞懂 Bean 的"存活范围(作用域)"和"一生流程(生命周期)",就吃透了 Spring 基础大半壁江山。


一、什么是 Bean?(前置理解)

在 Spring 中,Bean 就是由 Spring IoC 容器创建、管理、赋值、销毁的 Java 对象

我们自己 new 的对象,不受 Spring 管理;

交给 Spring 托管的对象,统一叫 Bean

Spring 对 Bean 的管控主要两件事:

  1. 作用域:这个 Bean 能活多久、全局有几个实例
  2. 生命周期:这个 Bean 从创建到销毁的完整执行流程

二、Bean 的 6 大作用域(重点!面试必考)

2.1 作用域核心概念

Bean 作用域 :定义 Spring 容器中 Bean 实例的数量存活的有效范围

Spring 官方提供 6 种作用域,其中 2 个常用核心作用域,4 个 Web 环境专属作用域。

2.2 六大作用域详细解析

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

特点

  • 整个 Spring IoC 容器中只会存在一个 Bean 实例
  • 全局共享,所有请求、所有线程共用这一个对象
  • 默认作用域(不指定 scope 就是 singleton)

创建时机

  • 默认:容器启动时立即创建(饿汉式)
  • @Lazy:首次使用时创建(懒汉式)

适用场景:无状态对象(Controller、Service、Dao、工具类)

注意坑单例 Bean 非线程安全,不要在 Bean 中定义成员变量存储请求数据,会出现数据错乱!

2. prototype(多例)

特点

  • 每次从容器中获取 Bean / 注入 Bean,都会创建一个全新的实例
  • 容器启动时不会创建,用一次、建一次
  • 容器只负责创建,不负责 prototype Bean 的销毁(垃圾回收由 JVM 管理)

适用场景:有状态对象、需要独立实例的对象(保存用户私有数据、临时对象)

3. request(Web 专属)

一次 HTTP 请求 对应一个 Bean 实例,请求结束,Bean 销毁。

4. session(Web 专属)

一个 用户会话 Session 对应一个 Bean 实例,会话过期/关闭,Bean 销毁。

5. application(Web 专属)

对应 整个 Web 应用,作用域等同于 ServletContext,全局唯一,和容器同生共死。

6. websocket(Web 专属)

一个 WebSocket 连接对应一个 Bean,连接断开则 Bean 销毁。

2.3 作用域快速总结表(记忆神器)

作用域 实例数量 创建时机 适用场景
singleton 全局1个 容器启动(默认) 无状态全局组件(默认)
prototype 每次获取1个新的 每次使用时 有状态、独立对象
request 单次请求1个 请求到来 请求级临时数据
session 单个会话1个 会话创建 用户会话数据

2.4 作用域注解使用方式

java 复制代码
// 默认单例
@Scope("singleton")
// 多例
@Scope("prototype")
// Web作用域同理
@Scope("request")

三、Bean 的完整生命周期(超清晰流程)

Bean 生命周期 :Spring Bean 从 实例创建 → 属性赋值 → 初始化 → 就绪使用 → 容器关闭销毁 的全过程。

整个流程分为 5 大核心阶段,我按执行顺序一步步拆解,附带每一步的作用。

3.1 完整生命周期执行顺序(背诵版)

1. 实例化(new 对象)→ 2. 属性填充(依赖注入)→ 3. 初始化前置处理 → 4. 初始化 → 5. 销毁

3.2 逐阶段详细讲解

阶段1:Bean 实例化

Spring 读取配置类/XML,扫描到 Bean 注解,通过反射调用无参构造器创建对象

此时:对象是空的,属性还没有赋值。

阶段2:属性填充(依赖注入 DI)

Spring 自动完成 属性赋值、自动装配(@Autowired、@Resource),把依赖的 Bean 注入进来。

此时:对象的属性已经赋值完成,但还没有执行初始化方法。

阶段3:Bean 后置处理器前置处理(BeanPostProcessor)

Spring 提供的扩展点,在初始化之前对 Bean 做增强、修改、包装

经典场景:AOP 代理就是在这里完成的!

阶段4:Bean 初始化(核心)

初始化内部又分为 4 个小步骤,顺序固定:

  1. 执行 Aware 接口方法
    如果 Bean 实现了 Spring 内置的 Aware 接口,会先执行对应方法,让 Bean 感知 Spring 容器资源:
  • BeanNameAware:获取当前 Bean 名称
  • BeanFactoryAware:获取 Bean 工厂
  • ApplicationContextAware:获取 Spring 上下文
  1. 执行 @PostConstruct 注解方法

    JSR250 规范注解,属性注入完成后执行,用于初始化资源、加载数据。

  2. 执行 InitializingBean 接口的 afterPropertiesSet()

    Spring 内置初始化接口,优先级低于 @PostConstruct。

  3. 执行自定义 init-method

    XML 或 @Bean 注解指定的初始化方法。

阶段5:Bean 就绪,正式使用

初始化完成后,Bean 正式存入单例池,对外提供服务,接收请求、执行业务逻辑。

阶段6:Bean 销毁

当 Spring 容器关闭(close)时,会执行销毁方法,仅针对 singleton 单例 Bean 生效!

销毁执行顺序:

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

重点结论

prototype 多例 Bean 容器不负责销毁,只有单例 Bean 会被容器统一销毁!

3.3 初始化方法优先级(面试高频)

优先级从高到低:

@PostConstruct > InitializingBean > 自定义 init-method

3.4 完整生命周期流程图(文字版,超好记)

容器启动 → 扫描Bean → 反射实例化DI依赖注入 → BeanPostProcessor前置处理 → Aware接口 → @PostConstruct → InitializingBean → init-method → Bean可用 → 容器关闭 → @PreDestroy → DisposableBean → destroy-method


四、重难点 & 面试高频问答(必背)

Q1:singleton 和 prototype 最大区别?

  • singleton:全局单例,容器启动创建,容器负责销毁,非线程安全
  • prototype:多实例,使用时创建,容器不销毁,线程独立安全

Q2:为什么 Controller/Service 用单例?

因为这些组件是无状态的,不存储用户私有数据,单例可以减少对象创建开销,提升性能。

Q3:Bean 是线程安全的吗?

  • singleton 单例 Bean:线程不安全(全局共享成员变量)
  • prototype 多例 Bean:线程安全(每个线程独立实例)

Q4:Bean 生命周期中,AOP 代理发生在哪个阶段?

BeanPostProcessor 后置处理阶段,在初始化完成后,对原生 Bean 进行动态代理增强。

Q5:多例 Bean 会执行销毁方法吗?

不会,Spring 容器只管理单例 Bean 的销毁,多例 Bean 由 JVM GC 回收。


五、最终总结(极简背诵版)

  1. 作用域核心:默认单例 singleton,多用多例 prototype,Web 环境专属 request/session/application/websocket。
  2. 生命周期核心流程:实例化 → 依赖注入 → 后置处理 → 初始化 → 使用 → 销毁。
  3. 初始化优先级:注解 > 接口 > 自定义方法。
  4. 唯一区别:单例容器全权管理,多例只用不管、不销毁。
相关推荐
NagatoYukee1 小时前
Spring Security基础部分学习
java·学习·spring
彦为君1 小时前
JavaSE-07-异常机制
java·开发语言·后端·python·spring
_Aaron___2 小时前
Spring AI 接入 MCP:工具调用不是“能调就行”,关键是边界治理
java·人工智能·spring
我是一颗柠檬2 小时前
【MySQL全面教学】MySQL性能优化实战Day13(2026年)
数据库·后端·sql·mysql·性能优化·database
向量引擎2 小时前
从零起步,如何打造专属向量引擎 API 中转工作流?
java·服务器·前端
LJianK12 小时前
普通接口,用到getter和setter方法的地方,jackson转换
java
辰海Coding2 小时前
MiniSpring框架学习-分解 Dispatcher
java·学习·spring·架构
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题 第84题】【Mysql篇】第14题:为什么用 InnoDB 存储引擎的表建议用整型的自增主键?
java·开发语言·数据库·mysql·面试
小江的记录本2 小时前
【JVM虚拟机】JVM调优:常用JVM参数、调优核心指标、OOM排查、GC日志分析、Arthas工具使用(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·后端·python·spring·面试