Spring Bean 生命周期解析

Spring Bean 生命周期解析

理解 Spring Bean 生命周期对于构建健壮应用至关重要。本文将通过一个简洁的示例,清晰展示从 Bean 定义到销毁的完整过程。

一、整体生命周期流程

首先,通过下面的完整流程图展示 Bean 生命周期的所有关键阶段:

二、配置与基础设置

配置类

java 复制代码
package cn.lee.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource("classpath:application.properties")
@ComponentScan(basePackages = "cn.lee.spring")
public class AppConfig {

    @Bean(initMethod = "customInit", destroyMethod = "customDestroy")
    public LifecycleDemoBean lifecycleDemoBean() {
        LifecycleDemoBean bean = new LifecycleDemoBean();
        // 可以在这里设置初始属性
        bean.setName("LifecycleDemo");
        return bean;
    }

    @Bean
    public CustomBeanPostProcessor customBeanPostProcessor() {
        return new CustomBeanPostProcessor();
    }
    
    @Bean
    public MyBeanFactoryPostProcessor myBeanFactoryPostProcessor() {
        return new MyBeanFactoryPostProcessor();
    }
}

属性配置文件

创建 application.properties

properties 复制代码

三、核心Bean实现

LifecycleDemoBean 类

java 复制代码
package cn.lee.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class LifecycleDemoBean implements 
        BeanNameAware, 
        BeanFactoryAware, 
        ApplicationContextAware,
        InitializingBean,
        DisposableBean {
    
    private String beanName;
    private String name;
    private int timeout;
    
    public LifecycleDemoBean() {
        System.out.println("=== 阶段1: 实例化 ===");
        System.out.println("1. 构造函数执行 - Bean对象创建");
    }
    
    public void setName(String name) {
        this.name = name;
        System.out.println("2. 设置属性: name = " + name);
    }
    
    public void setTimeout(int timeout) {
        this.timeout = timeout;
        System.out.println("2. 设置属性: timeout = " + timeout);
    }
    
    @Override
    public void setBeanName(String beanName) {
        this.beanName = beanName;
        System.out.println("=== 阶段2: Aware接口回调 ===");
        System.out.println("3. BeanNameAware.setBeanName() - Bean名称: " + beanName);
    }
    
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("4. BeanFactoryAware.setBeanFactory() - 设置BeanFactory");
    }
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("5. ApplicationContextAware.setApplicationContext() - 设置ApplicationContext");
    }
    
    @PostConstruct
    public void postConstruct() {
        System.out.println("=== 阶段3: 初始化 ===");
        System.out.println("7. @PostConstruct方法执行");
        System.out.println("   此时所有属性已设置,可以进行验证");
        validateConfiguration();
    }
    
    private void validateConfiguration() {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalStateException("Bean名称不能为空");
        }
        System.out.println("   配置验证通过: name=" + name + ", timeout=" + timeout);
    }
    
    @Override
    public void afterPropertiesSet() {
        System.out.println("8. InitializingBean.afterPropertiesSet()执行");
        System.out.println("   执行初始化逻辑");
    }
    
    public void customInit() {
        System.out.println("9. 自定义init方法执行");
        System.out.println("   Bean初始化完成,准备就绪");
    }
    
    public void executeBusinessLogic() {
        System.out.println("=== 阶段4: 使用阶段 ===");
        System.out.println("10. Bean执行业务方法");
        System.out.println("   当前Bean: " + beanName);
        System.out.println("   配置名称: " + name);
        System.out.println("   超时设置: " + timeout + "ms");
    }
    
    @PreDestroy
    public void preDestroy() {
        System.out.println("=== 阶段5: 销毁阶段 ===");
        System.out.println("11. @PreDestroy方法执行");
        System.out.println("   开始清理资源");
    }
    
    @Override
    public void destroy() {
        System.out.println("12. DisposableBean.destroy()执行");
        System.out.println("   执行标准销毁逻辑");
    }
    
    public void customDestroy() {
        System.out.println("13. 自定义destroy方法执行");
        System.out.println("   Bean销毁完成,资源已释放");
    }
}

BeanFactoryPostProcessor 实现

java 复制代码
package cn.lee.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.Ordered;

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
    
    @Override
    public void postProcessBeanFactory(
            ConfigurableListableBeanFactory beanFactory) throws BeansException {
        
        System.out.println("=== BeanFactoryPostProcessor 阶段 ===");
        
        String[] beanNames = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
            
            System.out.println("处理Bean定义: " + beanName);
            System.out.println("  Bean类: " + definition.getBeanClassName());
            System.out.println("  作用域: " + definition.getScope());
            
            if ("lifecycleDemoBean".equals(beanName)) {
                // 修改Bean定义
                definition.setLazyInit(false);
                definition.setInitMethodName("customInit");
                definition.setDestroyMethodName("customDestroy");
                System.out.println("  修改了lifecycleDemoBean的配置");
            }
        }
    }
    
    @Override
    public int getOrder() {
        return 0; // 执行顺序
    }
}

BeanPostProcessor 实现

java 复制代码
package cn.lee.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class CustomBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) 
            throws BeansException {
        
        if (bean instanceof LifecycleDemoBean) {
            System.out.println("6. BeanPostProcessor.postProcessBeforeInitialization()");
            System.out.println("   在初始化之前处理: " + beanName);
            System.out.println("   可以修改Bean实例或返回代理");
        }
        
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) 
            throws BeansException {
        
        if (bean instanceof LifecycleDemoBean) {
            System.out.println("10. BeanPostProcessor.postProcessAfterInitialization()");
            System.out.println("   在初始化之后处理: " + beanName);
            System.out.println("   Bean已完全初始化,可以进行包装");
        }
        
        return bean;
    }
}

四、生命周期序列图

LifecycleDemoBean BeanPostProcessor BeanFactoryPostProcessor Spring容器 LifecycleDemoBean BeanPostProcessor BeanFactoryPostProcessor Spring容器 阶段0: 配置加载 阶段1: Bean定义后处理 阶段2: 实例化 阶段3: 属性设置 阶段4: Aware接口 阶段5: 初始化前处理 阶段6: 初始化方法 阶段7: 初始化后处理 阶段8: 使用阶段 阶段9: 销毁 加载AppConfig类 解析@Bean注解方法 创建BeanDefinition postProcessBeanFactory() 读取和修改BeanDefinition 返回修改后的定义 1. 调用构造函数() Bean实例创建 2. setName("LifecycleDemo") 2. setTimeout(5000) 3. setBeanName("lifecycleDemoBean") 4. setBeanFactory() 5. setApplicationContext() 6. postProcessBeforeInitialization() 返回Bean实例 7. @PostConstruct postConstruct() 8. afterPropertiesSet() 9. customInit() 10. postProcessAfterInitialization() 返回最终Bean Bean准备就绪 调用executeBusinessLogic() 11. @PreDestroy preDestroy() 12. destroy() 13. customDestroy()

五、测试与验证

测试主程序

java 复制代码
package cn.lee.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class LifecycleTest {
    public static void main(String[] args) {
        System.out.println("=======================================");
        System.out.println("Spring Bean 生命周期测试开始");
        System.out.println("=======================================\n");
        
        // 创建应用上下文
        AnnotationConfigApplicationContext context = 
                new AnnotationConfigApplicationContext();
        
        // 注册配置类
        context.register(AppConfig.class);
        
        System.out.println("1. 开始刷新容器...");
        context.refresh();
        
        System.out.println("\n2. 获取Bean并执行业务逻辑...");
        
        // 获取Bean实例
        LifecycleDemoBean bean = context.getBean(LifecycleDemoBean.class);
        bean.executeBusinessLogic();
        
        System.out.println("\n3. 容器信息统计");
        System.out.println("Bean定义数量: " + context.getBeanDefinitionCount());
        
        String[] beanNames = context.getBeanDefinitionNames();
        System.out.println("Bean列表:");
        for (String name : beanNames) {
            System.out.println("  - " + name + ": " + 
                    context.getBean(name).getClass().getSimpleName());
        }
        
        System.out.println("\n=======================================");
        System.out.println("关闭Spring容器");
        System.out.println("=======================================");
        context.close();
        
        System.out.println("\n测试完成。");
    }
}

输出结果

复制代码
=======================================
Spring Bean 生命周期测试开始
=======================================

1. 开始刷新容器...
=== BeanFactoryPostProcessor 阶段 ===
处理Bean定义: org.springframework.context.annotation.internalConfigurationAnnotationProcessor
  Bean类: org.springframework.context.annotation.ConfigurationClassPostProcessor
  作用域: 
处理Bean定义: org.springframework.context.annotation.internalAutowiredAnnotationProcessor
  Bean类: org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
  作用域: 
处理Bean定义: org.springframework.context.annotation.internalCommonAnnotationProcessor
  Bean类: org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
  作用域: 
处理Bean定义: org.springframework.context.event.internalEventListenerProcessor
  Bean类: org.springframework.context.event.EventListenerMethodProcessor
  作用域: 
处理Bean定义: org.springframework.context.event.internalEventListenerFactory
  Bean类: org.springframework.context.event.DefaultEventListenerFactory
  作用域: 
处理Bean定义: appConfig
  Bean类: cn.lee.spring.AppConfig$$SpringCGLIB$$0
  作用域: singleton
处理Bean定义: lifecycleDemoBean
  Bean类: null
  作用域: 
  修改了lifecycleDemoBean的配置
处理Bean定义: customBeanPostProcessor
  Bean类: null
  作用域: 
处理Bean定义: myBeanFactoryPostProcessor
  Bean类: null
  作用域: 
=== 阶段1: 实例化 ===
1. 构造函数执行 - Bean对象创建
2. 设置属性: name = LifecycleDemo
=== 阶段2: Aware接口回调 ===
3. BeanNameAware.setBeanName() - Bean名称: lifecycleDemoBean
4. BeanFactoryAware.setBeanFactory() - 设置BeanFactory
5. ApplicationContextAware.setApplicationContext() - 设置ApplicationContext
6. BeanPostProcessor.postProcessBeforeInitialization()
   在初始化之前处理: lifecycleDemoBean
   可以修改Bean实例或返回代理
=== 阶段3: 初始化 ===
7. @PostConstruct方法执行
   此时所有属性已设置,可以进行验证
   配置验证通过: name=LifecycleDemo, timeout=0
8. InitializingBean.afterPropertiesSet()执行
   执行初始化逻辑
9. 自定义init方法执行
   Bean初始化完成,准备就绪
10. BeanPostProcessor.postProcessAfterInitialization()
   在初始化之后处理: lifecycleDemoBean
   Bean已完全初始化,可以进行包装

2. 获取Bean并执行业务逻辑...
=== 阶段4: 使用阶段 ===
10. Bean执行业务方法
   当前Bean: lifecycleDemoBean
   配置名称: LifecycleDemo
   超时设置: 0ms

3. 容器信息统计
Bean定义数量: 9
Bean列表:
  - org.springframework.context.annotation.internalConfigurationAnnotationProcessor: ConfigurationClassPostProcessor
  - org.springframework.context.annotation.internalAutowiredAnnotationProcessor: AutowiredAnnotationBeanPostProcessor
  - org.springframework.context.annotation.internalCommonAnnotationProcessor: CommonAnnotationBeanPostProcessor
  - org.springframework.context.event.internalEventListenerProcessor: EventListenerMethodProcessor
  - org.springframework.context.event.internalEventListenerFactory: DefaultEventListenerFactory
  - appConfig: AppConfig$$SpringCGLIB$$0
  - lifecycleDemoBean: LifecycleDemoBean
  - customBeanPostProcessor: CustomBeanPostProcessor
  - myBeanFactoryPostProcessor: MyBeanFactoryPostProcessor

=======================================
关闭Spring容器
=======================================
=== 阶段5: 销毁阶段 ===
11. @PreDestroy方法执行
   开始清理资源
12. DisposableBean.destroy()执行
   执行标准销毁逻辑
13. 自定义destroy方法执行
   Bean销毁完成,资源已释放

测试完成。

六、生命周期阶段

阶段1:Bean定义加载(配置阶段)

  • Spring容器读取 AppConfig 配置类
  • 解析 @Bean 注解的方法,创建 BeanDefinition 对象
  • 注册 BeanDefinition 到容器中
  • 执行 BeanFactoryPostProcessor 修改 Bean 定义

阶段2:实例化阶段

  • 调用构造函数创建 Bean 实例
  • 设置 Bean 的属性值(依赖注入)

阶段3:Aware接口回调

  • 调用 BeanNameAware.setBeanName() 设置 Bean 名称
  • 调用 BeanFactoryAware.setBeanFactory() 设置 BeanFactory
  • 调用 ApplicationContextAware.setApplicationContext() 设置 ApplicationContext

阶段4:初始化前处理

  • 执行 BeanPostProcessor.postProcessBeforeInitialization()
  • 可以在初始化前修改 Bean 或返回代理

阶段5:初始化方法执行

  • 执行 @PostConstruct 注解的方法
  • 执行 InitializingBean.afterPropertiesSet() 方法
  • 执行自定义的 init 方法

阶段6:初始化后处理

  • 执行 BeanPostProcessor.postProcessAfterInitialization()
  • Bean 完全初始化,可以返回包装后的实例

阶段7:使用阶段

  • Bean 准备就绪,可以执行业务方法
  • 在应用程序中被使用

阶段8:销毁阶段

  • 容器关闭时执行 @PreDestroy 注解的方法
  • 执行 DisposableBean.destroy() 方法
  • 执行自定义的 destroy 方法

七、关键扩展

通过示例展示Spring 生命周期的关键扩展:

  1. BeanFactoryPostProcessor - 修改 Bean 定义
  2. BeanPostProcessor - 修改 Bean 实例
  3. Aware 接口系列 - 获取容器信息
  4. @PostConstruct / @PreDestroy - 标准初始化/销毁
  5. InitializingBean / DisposableBean - Spring 特定接口
  6. 自定义 init/destroy 方法 - 配置指定的方法
相关推荐
野生的码农4 小时前
码农的妇产科实习记录
android·java·人工智能
盖世英雄酱581365 小时前
Java 组长年终总结:靠 AI 提效 50%,25 年搞副业只赚 4k?
后端·程序员·trae
毕设源码-赖学姐6 小时前
【开题答辩全过程】以 高校人才培养方案管理系统的设计与实现为例,包含答辩的问题和答案
java
+VX:Fegn08956 小时前
计算机毕业设计|基于springboot + vue在线音乐播放系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
一起努力啊~6 小时前
算法刷题-二分查找
java·数据结构·算法
小途软件6 小时前
高校宿舍访客预约管理平台开发
java·人工智能·pytorch·python·深度学习·语言模型
J_liaty6 小时前
Java版本演进:从JDK 8到JDK 21的特性革命与对比分析
java·开发语言·jdk
code bean6 小时前
Flask图片服务在不同网络接口下的路径解析问题及解决方案
后端·python·flask
+VX:Fegn08956 小时前
计算机毕业设计|基于springboot + vue律师咨询系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
努力的小郑6 小时前
2025年度总结:当我在 Cursor 里敲下 Tab 的那一刻,我知道时代变了
前端·后端·ai编程