Spring Bean 生命周期

目录

  • 概览
  • 生命周期总览(含流程图)
  • 核心接口与机制
  • 实战示例(代码)
  • 可利用生命周期实现的场景
  • 源码层级简析(关键方法)
  • 常见坑与建议
  • 总结

概览

在 Spring 容器中,Bean 从创建到销毁会经历一系列阶段:定义解析 → 实例化 → 依赖注入 → 回调与初始化 → 可用 → 销毁。这些阶段是容器管理对象、插入钩子(例如 AOP、事件、初始化任务)以及实现自动化的一套机制的基础。


生命周期总览(含流程图)

1 BeanDefinition 解析 2 实例化 Instantiation 3 属性填充 Dependency Injection 4 Aware 接口回调 5 BeanPostProcessor 前置处理 6 初始化 init-method 或 InitializingBean 7 BeanPostProcessor 后置处理 8 Bean 可用 使用阶段 9 容器关闭时销毁 Destroy

阶段要点(简略):

  • BeanDefinition 解析:从注解或 XML/JavaConfig 读取元数据。
  • 实例化:通过反射或构造器创建对象。
  • 属性填充:完成依赖注入(构造注入 / 设值注入)。
  • Aware 回调:如 BeanNameAwareApplicationContextAware 获取容器上下文。
  • BeanPostProcessor:在初始化前后对 Bean 做增强(常用于创建代理)。
  • 初始化:@PostConstruct / InitializingBean#afterPropertiesSet() / 自定义 init-method
  • 销毁:@PreDestroy / DisposableBean#destroy() 在容器关闭时执行清理。

核心接口与机制

接口 / 注解 阶段 作用
BeanNameAware Aware 获取 Bean 名称
BeanFactoryAware Aware 获取 BeanFactory 引用
ApplicationContextAware Aware 获取 ApplicationContext
InitializingBean / @PostConstruct 初始化 属性注入后执行初始化逻辑
DisposableBean / @PreDestroy 销毁 容器关闭前释放资源
BeanPostProcessor 前后置处理 创建代理、注入增强逻辑
BeanFactoryPostProcessor 容器启动早期 修改 BeanDefinition 或动态注册 Bean

实战示例(代码)

1) 使用 @PostConstruct@PreDestroy

复制代码
@Component
public class CacheService {

    @PostConstruct
    public void initCache() {
        // 启动时预热缓存
        System.out.println("初始化缓存");
        // loadCache();
    }

    @PreDestroy
    public void shutdown() {
        // 关闭时释放资源
        System.out.println("清理缓存资源");
        // closeConnections();
    }
}

2) 使用 BeanPostProcessor 做简单增强(示例)

复制代码
@Component
public class LoggingBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 在初始化前记录
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 在初始化后可以返回代理
        if (bean instanceof MyService) {
            // return ProxyFactory.getProxy(bean);
        }
        return bean;
    }
}

3) 使用 SmartLifecycle 控制启动顺序(长生命周期组件)

复制代码
@Component
public class MyServiceLifecycle implements SmartLifecycle {

    private boolean running = false;

    @Override
    public void start() {
        // 在上下文刷新后按顺序启动
        running = true;
    }

    @Override
    public void stop() {
        running = false;
    }

    @Override
    public boolean isRunning() {
        return running;
    }

    @Override
    public int getPhase() {
        // phase 决定启动与停止顺序,值越小越先启动
        return 0;
    }
}

可利用生命周期实现的场景

  • 配置加载与验证:在初始化阶段加载并校验外部配置(数据库、第三方服务)。
  • 缓存预热 / 线程池创建:在启动时初始化必须的资源,避免首次请求阻塞。
  • 自动注册:应用启动时自动向注册中心或配置中心注册自身信息。
  • 运行时增强 :通过 BeanPostProcessor 在 Bean 初始化后替换为代理以实现 AOP、权限或度量统计。
  • 优雅关闭 :在 @PreDestroyDisposableBean 中释放连接、持久化内存状态、发送下线事件。

源码层级简析(关键方法)

Spring 的 Bean 创建核心在 AbstractAutowireCapableBeanFactory,伪代码流程如下:

复制代码
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) {
    // 1. 实例化
    Object bean = createBeanInstance(beanName, mbd, args);

    // 2. 属性注入
    populateBean(beanName, mbd, instanceWrapper);

    // 3. before init
    bean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);

    // 4. init
    invokeInitMethods(beanName, bean, mbd);

    // 5. after init
    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);

    return bean;
}

理解此流程有助于在合适的环节注入自定义逻辑(如动态代理、自动化校验、注册等)。


常见坑与建议

场景 问题 建议
注解不生效 @PostConstruct / @PreDestroy 不触发 确保类被 Spring 管理(如 @Component
循环依赖 构造器注入导致循环 尽量使用构造器注入保证不可变,或对部分依赖使用 @Lazy
初始化耗时 阻塞启动 将耗时任务异步化或延迟执行,避免阻塞容器启动
资源未释放 @PreDestroy 不触发 使用 ApplicationContext 正常关闭(context.close()),避免强制退出 JVM
滥用 BeanPostProcessor 性能下降 限定处理对象类型,避免每个 Bean 都做大量反射/代理

总结

Spring Bean 生命周期是理解整个 Spring IoC 容器运行机制的核心

BeanDefinition 解析 → 实例化 → 依赖注入 → 初始化 → 使用 → 销毁 ,每一步都为容器提供了精确的可插拔扩展点,保证了框架的灵活性与可扩展性。

在工程实践中,合理利用生命周期机制,可以实现:

  • 缓存预热:在应用启动阶段提前加载热点数据,提升首屏性能;
  • 自动注册 / 自动上报:在初始化阶段自动向注册中心、配置中心或监控系统上报实例;
  • 代理增强与拦截 :通过 BeanPostProcessor 动态创建代理,实现 AOP、日志、安全控制;
  • 资源回收与优雅关闭:在销毁阶段释放连接、保存状态,保障系统平滑停机;
  • 启动验证与健康检测:在容器完成加载后执行自检逻辑,确保依赖和外部服务可用。
相关推荐
CodeAmaz4 分钟前
Spring编程式事务详解
java·数据库·spring
没有bug.的程序员5 分钟前
微服务基础设施清单:必须、应该、可以、无需的四级分类指南
java·jvm·微服务·云原生·容器·架构
武子康8 分钟前
Java-204 RabbitMQ Connection/Channel 工作流程:AMQP 发布消费、抓包帧结构与常见坑
java·分布式·消息队列·rabbitmq·ruby·java-activemq
郑州光合科技余经理10 分钟前
海外国际版同城服务系统开发:PHP技术栈
java·大数据·开发语言·前端·人工智能·架构·php
appearappear20 分钟前
Mac 上重新安装了Cursor 2.2.30,重新配置 springboot 过程记录
java·spring boot·后端
CryptoRzz29 分钟前
日本股票 API 对接实战指南(实时行情与 IPO 专题)
java·开发语言·python·区块链·maven
程序员水自流31 分钟前
MySQL数据库自带系统数据库功能介绍
java·数据库·mysql·oracle
谷哥的小弟35 分钟前
Spring Framework源码解析——RequestContext
java·后端·spring·框架·源码
天远Date Lab41 分钟前
Java微服务实战:聚合型“全能小微企业报告”接口的调用与数据清洗
java·大数据·python·微服务
lizz311 小时前
C++操作符重载深度解析
java·c++·算法