news 2026/4/20 3:06:33

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/4/19 3:30:33

ComfyUI-SeedVR2视频超分模块:5个高效配置技巧与性能优化指南

ComfyUI-SeedVR2视频超分模块:5个高效配置技巧与性能优化指南 【免费下载链接】ComfyUI-SeedVR2_VideoUpscaler Non-Official SeedVR2 Vudeo Upscaler for ComfyUI 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-SeedVR2_VideoUpscaler ComfyUI-Seed…

作者头像 李华
网站建设 2026/4/17 15:22:33

论文目录工具推荐:9大平台+自动排版排名

论文目录工具推荐:9大平台自动排版排名 还在为论文目录排版发愁?别担心!今天为大家带来9款超实用的论文目录生成工具,从一键排版到智能优化,总有一款适合你!先来看看各工具的核心特点对比: 工具…

作者头像 李华
网站建设 2026/4/18 1:53:27

计算机毕业设计springboot基于JAVA的酒店客房管理系统 基于Spring Boot框架的Java酒店客房智能化管理系统设计与实现 Java技术驱动的Spring Boot酒店客房管理平台开发

计算机毕业设计springboot基于JAVA的酒店客房管理系统51sl19(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。 随着互联网技术的飞速发展,酒店行业的管理方式也在不断…

作者头像 李华
网站建设 2026/4/20 0:39:15

Phi-3-Mini-4K-Instruct 模型完整使用指南

Phi-3-Mini-4K-Instruct 模型完整使用指南 【免费下载链接】Phi-3-mini-4k-instruct-gguf 项目地址: https://ai.gitcode.com/hf_mirrors/ai-gitcode/Phi-3-mini-4k-instruct-gguf 项目概述 Phi-3-Mini-4K-Instruct 是微软推出的轻量级语言模型,以其出色的…

作者头像 李华
网站建设 2026/4/18 10:45:46

Sapiens智能视觉系统:如何构建永不宕机的故障恢复机制

Sapiens智能视觉系统:如何构建永不宕机的故障恢复机制 【免费下载链接】sapiens High-resolution models for human tasks. 项目地址: https://gitcode.com/gh_mirrors/sa/sapiens 当人类视觉系统面临复杂场景时,Sapiens展现出了令人惊叹的自愈能…

作者头像 李华
网站建设 2026/4/17 13:50:45

黑苹果配置终极指南:OpCore Simplify一键生成完美EFI

黑苹果配置终极指南:OpCore Simplify一键生成完美EFI 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在为复杂的黑苹果配置而头痛不已吗…

作者头像 李华