news 2026/2/3 23:14:18

Spring Bean生命周期- BeanDefinition 加载与 BeanFactoryPostProcessor BeanPostProcessor

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Bean生命周期- BeanDefinition 加载与 BeanFactoryPostProcessor BeanPostProcessor

使用细节

  1. 默认是单例singleton,在启动容器时,默认就会创建,并放入到singletonObjects集合中存储实例
  2. 当 设置为多实例机制后,该bean是在getBean()时才创建
  3. 如果是单例singleton,同时希望在getBean时才创建,可以 指定懒加载 lazy-init=“true” (注意默认是false)
  4. 通常情况下, lazy-init 就使用默认值false ,在开发看来,用空间换时间是值得的,除非有特殊的要求.
  5. 如果scope=“prototype” 这时你的 lazy-init 属性的值不管是 true,还是false 都是在getBean时候,才创建对象.

BeanDefinition 与 singletonObjects 的区别

BeanDefinition

  • 存储内容: 存储 bean 的元数据信息(配置信息)
  • 包含内容: bean 的类名、作用域(scope)、属性值、依赖关系、初始化方法、销毁方法等
  • 创建时机: Spring 容器启动时,解析 XML/注解配置后创建
  • 存储位置: 保存在 BeanFactory/ApplicationContext 中,作为创建 bean 实例的模板

singletonObjects

  • 存储内容: 存储单例 bean 的实际实例对象
  • 包含内容: 已经完成实例化、属性注入、初始化的 bean 对象
  • 创建时机: 单例 bean 实例化后(默认启动时,懒加载则第一次 getBean 时)
  • 存储位置: 作为单例缓存,避免重复创建相同实例
  • 非单例 bean 的处理:非单例 bean(如 prototype 作用域)不会被放入 singletonObjects

不同作用域的 bean 存储方式

  1. singleton(单例): 实例放入singletonObjects缓存,重复使用
  2. prototype(原型/多实例): 每次调用getBean()都创建新实例,不缓存,使用后由调用者负责销毁
  3. request(请求): 每个 HTTP 请求创建新实例,请求结束后销毁(仅 Web 环境)
  4. session(会话): 每个 HTTP 会话创建新实例,会话结束后销毁(仅 Web 环境)
  5. application(应用): 每个 ServletContext 创建新实例,应用停止后销毁(仅 Web 环境)

结论: 只有singleton作用域的 bean 会被放入singletonObjects集合,其他作用域的 bean 不会被缓存。

Bean 的生命周期

生命周期概述

Spring Bean 的生命周期是指从 Bean 被创建、初始化、使用到最终销毁的完整过程。Spring 容器负责管理 Bean 的整个生命周期,确保 Bean 在合适的时机完成相应的操作。

详细阶段说明

  1. 根据 xml 配置文件或注解配置, Spring 容器会解析 Bean 定义,并创建一个 BeanDefinition 对象, 该对象包含了 Bean 的元数据信息(类名,作用域,属性值,依赖关系等)
  2. 执行 BeanFactoryPostProcessor: 在所有 BeanDefinition 加载完成后,Bean 实例化之前,Spring 容器会调用所有实现了 BeanFactoryPostProcessor 接口的类的postProcessBeanFactory方法。这些方法可以修改 BeanDefinition 的元数据信息(如属性值、作用域等)
  3. 通过反射机制,根据 BeanDefinition 中的类名,调用对应的构造函数,创建 Bean 的实例.
  4. 属性注入 (DI) : Spring 容器会根据 BeanDefinition 中的依赖关系,将对应的 Bean 实例注入到目标 Bean 的属性中.
  5. 初始化 : 调用 Bean 的初始化方法(如实现 InitializingBean 接口的 afterPropertiesSet 方法,或指定的 init-method 方法)
  6. 通过getBean()方法获取Bean实例时,Spring容器会返回该Bean的实例.
  7. 销毁 : 当 Bean 实例不再需要时,Spring 容器会调用 Bean 的销毁方法(如实现 DisposableBean 接口的 destroy 方法,或指定的 destroy-method 方法)
1. BeanDefinition 加载与 BeanFactoryPostProcessor 执行
  • 时机: Spring 容器启动时,所有 BeanDefinition 加载完成后,Bean 实例化之前
  • 操作:
    • Spring 容器解析 XML/注解配置,创建所有 BeanDefinition 对象
    • 调用所有实现了BeanFactoryPostProcessor接口的类的postProcessBeanFactory方法
  • 作用:
    • 可以修改 BeanDefinition 的元数据信息(如属性值、作用域、初始化方法等)
    • 典型应用:PropertyPlaceholderConfigurer(处理 ${} 占位符)、CustomScopeConfigurer(注册自定义作用域)
  • 执行特点: 在所有 Bean 实例化之前执行,且只执行一次
2. 实例化(Instantiation)
  • 时机: Spring 容器根据 BeanDefinition 创建 Bean 实例
  • 操作: 调用 Bean 的构造函数创建对象
  • 结果: 获得一个原始的 Bean 实例(尚未设置任何属性)
3. 属性注入(Populate)
  • 时机: 实例化完成后
  • 操作: 根据配置(XML/注解)将依赖注入到 Bean 的属性中
  • 实现: 调用 setter 方法或通过构造函数注入依赖
  • 这里的"bean"指: 刚刚完成实例化阶段(通过构造函数创建)的原始 Bean 实例。此时它已经是一个 Java 对象,但尚未设置任何属性值,处于"原始状态"。Spring 容器会将配置中定义的属性值、依赖对象等注入到这个原始实例中,使其成为一个完整可用的 Bean。

例如:当实例化 User 类获得一个 user 对象后,此时 user.name 可能为 null(默认值),属性注入阶段会将配置的 name 值注入到 user 对象中。

4. 初始化前(Before Initialization)
  • 时机: 属性注入完成后
  • 操作: 调用 BeanPostProcessor 的postProcessBeforeInitialization方法
  • 作用: 可以在 Bean 初始化前对其进行增强处理
5. 初始化(Initialization)
  • 时机: 初始化前阶段完成后
  • 操作: 执行自定义的初始化逻辑
  • 实现方式:
    • 实现InitializingBean接口的afterPropertiesSet()方法
    • 在配置中指定init-method属性
    • 使用@PostConstruct注解标记初始化方法
6. 初始化后(After Initialization)
  • 时机: 初始化完成后
  • 操作: 调用 BeanPostProcessor 的postProcessAfterInitialization方法
  • 作用: 可以在 Bean 初始化后进行代理创建或其他增强处理
7. 加入 IoC 容器(Add to IoC Container)
  • 时机: 初始化后阶段完成后(仅针对 singleton 作用域)
  • 操作: Spring 容器将完全初始化的单例 Bean 放入singletonObjects缓存中
  • 作用: 后续调用getBean()时直接从缓存返回,避免重复创建
  • 非单例 Bean 的处理: prototype、request、session、application 等作用域的 Bean不会被加入 singletonObjects 缓存
8. 使用阶段(In Use)
  • 时机: Bean 完全初始化后(单例 Bean 已加入容器缓存)
  • 操作: Bean 可以被应用程序使用(通过getBean()获取)
  • 特点:
    • 单例 Bean:从singletonObjects缓存获取,重复使用
    • 原型 Bean:每次调用getBean()都创建新实例,使用后由调用者负责管理
    • 其他作用域:根据各自作用域规则创建和管理
9. 销毁前(Before Destruction)
  • 时机: 容器关闭前(仅单例 Bean)
  • 操作: 执行自定义的销毁逻辑
  • 实现方式:
    • 实现DisposableBean接口的destroy()方法
    • 在配置中指定destroy-method属性
    • 使用@PreDestroy注解标记销毁方法
10. 销毁(Destruction)
  • 时机: 销毁前阶段完成后
  • 操作: 释放 Bean 占用的资源
  • 注意: 仅单例 Bean 会被容器管理销毁,原型 Bean 由调用者负责销毁

生命周期回调方法示例

publicclassUser{privateStringname;// 构造函数(实例化阶段调用)publicUser(){System.out.println("1. User 构造函数被调用(实例化)");}// setter 方法(属性注入阶段调用)publicvoidsetName(Stringname){this.name=name;System.out.println("2. setName 被调用(属性注入)");}// InitializingBean 接口方法(初始化阶段调用)@OverridepublicvoidafterPropertiesSet(){System.out.println("3. afterPropertiesSet 被调用(InitializingBean 接口)");}// 自定义初始化方法(配置 init-method 指定)publicvoidinit(){System.out.println("4. init 方法被调用(自定义初始化)");}// 业务方法(使用阶段调用)publicvoidsayHello(){System.out.println("5. sayHello 方法被调用(使用中)");}// DisposableBean 接口方法(销毁阶段调用)@Overridepublicvoiddestroy(){System.out.println("6. destroy 方法被调用(DisposableBean 接口)");}// 自定义销毁方法(配置 destroy-method 指定)publicvoidcleanup(){System.out.println("7. cleanup 方法被调用(自定义销毁)");}}

不同作用域对生命周期的影响

作用域实例化时机初始化时机销毁时机容器管理销毁
singleton容器启动(默认)/第一次 getBean实例化后立即初始化容器关闭前
prototype每次 getBean实例化后立即初始化调用者负责销毁
request每个 HTTP 请求开始实例化后立即初始化HTTP 请求结束是(Web环境)
session每个 HTTP 会话开始实例化后立即初始化HTTP 会话结束是(Web环境)
application应用启动实例化后立即初始化应用停止是(Web环境)

关系说明

  1. Spring 先读取配置创建BeanDefinition(元数据)
  2. 然后根据BeanDefinition的配置创建实际的 bean 实例
  3. 单例实例创建完成后,会被放入singletonObjects缓存中
  4. 后续调用getBean()获取单例时,直接从缓存返回,不再重新创建

因此,“存储到实体类中 BeanDefinition” 和 “放入到 singletonObjects 集合” 描述的是 Spring 管理 bean 的不同阶段

  • BeanDefinition 是配置模板
  • singletonObjects 是实例缓存
    两者都是正确的,只是描述了 bean 生命周期中的不同环节。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/29 1:12:04

Monaco Editor深度集成指南:从原理到实战的完整解决方案

Monaco Editor深度集成指南:从原理到实战的完整解决方案 【免费下载链接】monaco-editor A browser based code editor 项目地址: https://gitcode.com/gh_mirrors/mo/monaco-editor 你是否在项目中使用Monaco Editor时遇到过这些问题?明明按照文…

作者头像 李华
网站建设 2026/2/1 19:53:37

开源四足机器人Mini Pupper:从入门到精通的完整实战指南

开源四足机器人Mini Pupper:从入门到精通的完整实战指南 【免费下载链接】QuadrupedRobot Open-Source,ROS Robot Dog Kit 项目地址: https://gitcode.com/gh_mirrors/qu/QuadrupedRobot Mini Pupper是一款基于ROS和OpenCV的开源四足机器人套件,专…

作者头像 李华
网站建设 2026/1/31 5:05:08

XCOM V2.6:嵌入式开发的终极串口调试解决方案

XCOM V2.6:嵌入式开发的终极串口调试解决方案 【免费下载链接】XCOMV2.6正点原子串口调试工具最新版 XCOM V2.6是一款由正点原子开发的串口调试工具,专为嵌入式开发人员和电子爱好者设计。该版本在原有功能的基础上进行了多项修复和优化,提升…

作者头像 李华
网站建设 2026/2/3 15:13:47

负载均衡集群LVS详解及配置

情景导入当电商平台大促时,几十万用户同时涌入抢单,有的服务器忙到崩溃、有的却闲着没事,用户要么页面卡半天刷不出来,要么付完款订单却没生成,甚至某台服务器突然宕机导致一批用户直接无法操作,怎么才能让…

作者头像 李华
网站建设 2026/1/31 7:19:54

论文查重合格标准:从AI工具到学术规范的深度解析

论文查重合格标准:从AI工具到学术规范的深度解析 AI工具对比速览表 工具名称 核心功能 查重效率 适用场景 独特优势 AIbiye 论文降重与改写 高 初稿修改阶段 语义保持最佳 AIcheck 多平台查重比对 中高 终稿前检测 数据库最全面 AskPaper 文献溯源…

作者头像 李华