spring中bean的生命周期

Bean 的生命周期是 Spring 框架的核心知识点之一,它描述了一个 Bean 从被 Spring 容器加载、实例化、初始化,到最终销毁的全流程。相比于 SpringBoot 应用的全局生命周期,Bean 的生命周期更聚焦于单个 Bean 实例的生老病死

一、各阶段详细解析

阶段 核心行为 扩展 / 自定义方式
1. Bean 定义加载 Spring 容器扫描@Component、@Bean等注解,解析成BeanDefinition(Bean 的元数据),存入容器 无直接扩展点,可通过BeanDefinitionRegistryPostProcessor修改 Bean 定义
2. 实例化 Bean 根据 Bean 定义创建对象(调用构造方法),此时只是一个空对象,属性未赋值 可通过构造方法注入简单属性,但核心依赖注入在下一步
3. 属性注入(DI) Spring 将依赖的 Bean(如@Autowired标注的属性)赋值给当前 Bean,完成依赖注入 常用@Autowired、@Resource、构造方法注入、setter 注入
4. 感知接口回调(Aware 系列) Bean 感知自身在容器中的信息,Spring 自动调用这些接口的方法:
- BeanNameAware:设置 Bean 在容器中的名称
- BeanFactoryAware:设置当前 BeanFactory
- ApplicationContextAware:设置 ApplicationContext
实现对应的 Aware 接口,获取容器上下文信息
5. BeanPostProcessor 前置处理 全局扩展点,所有 Bean 初始化前都会执行这个方法,可修改 Bean 实例 实现BeanPostProcessor接口,重写postProcessBeforeInitialization
6. 初始化回调(核心扩展点) Bean 完成属性注入后,执行初始化逻辑,优先级:
① InitializingBean接口(afterPropertiesSet)
② @PostConstruct注解方法
③ 自定义init-method(XML/@Bean 指定)
最常用的扩展点,用于初始化资源(如连接池、缓存)
7. BeanPostProcessor 后置处理 全局扩展点,所有 Bean 初始化后都会执行,可最终修改 Bean 实例(如 AOP 动态代理) 实现BeanPostProcessor接口,重写postProcessAfterInitialization
8. Bean 就绪 Bean 完全初始化完成,可被应用程序使用(如注入到其他 Bean、被调用) 无扩展点,此时 Bean 处于可用状态
9. 销毁回调(核心扩展点) 容器关闭时触发 Bean 销毁,优先级:
① @PreDestroy注解方法
② DisposableBean接口(destroy)
③ 自定义destroy-method
用于释放资源(如关闭连接池、清理缓存)
10. Bean 销毁 Bean 实例被回收,释放内存(最终由 JVM 垃圾回收) 无扩展点

二、完整代码示例(验证执行顺序)
下面是一个可直接运行的示例,覆盖 Bean 生命周期的所有核心阶段,执行后能清晰看到各方法的调用顺序:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

// 1. 定义Bean,实现多个感知接口和初始化/销毁接口
@Component
public class MyLifeCycleBean implements 
        BeanNameAware, BeanFactoryAware, ApplicationContextAware, 
        InitializingBean, DisposableBean {

    // 注入一个简单属性(模拟DI)
    private String name;

    // 构造方法(实例化阶段调用)
    public MyLifeCycleBean() {
        System.out.println("【2. 实例化Bean】调用构造方法创建对象");
    }

    // setter方法(属性注入阶段调用)
    public void setName(String name) {
        this.name = name;
        System.out.println("【3. 属性注入】设置name属性:" + name);
    }

    // -------------------- Aware接口回调 --------------------
    @Override
    public void setBeanName(String beanName) {
        System.out.println("【4. BeanNameAware】设置Bean名称:" + beanName);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("【4. BeanFactoryAware】设置BeanFactory:" + beanFactory.getClass().getSimpleName());
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("【4. ApplicationContextAware】设置ApplicationContext:" + applicationContext.getClass().getSimpleName());
    }

    // -------------------- 初始化回调 --------------------
    @PostConstruct
    public void postConstructMethod() {
        System.out.println("【6. 初始化】执行@PostConstruct注解方法");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【6. 初始化】执行InitializingBean接口的afterPropertiesSet方法");
    }

    // 自定义init-method(需在@Bean中指定)
    public void customInitMethod() {
        System.out.println("【6. 初始化】执行自定义init-method方法");
    }

    // -------------------- 销毁回调 --------------------
    @PreDestroy
    public void preDestroyMethod() {
        System.out.println("【9. 销毁】执行@PreDestroy注解方法");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("【9. 销毁】执行DisposableBean接口的destroy方法");
    }

    // 自定义destroy-method(需在@Bean中指定)
    public void customDestroyMethod() {
        System.out.println("【9. 销毁】执行自定义destroy-method方法");
    }
}

// 2. 自定义BeanPostProcessor(全局前置/后置处理)
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof MyLifeCycleBean) {
            System.out.println("【5. BeanPostProcessor前置处理】处理Bean:" + beanName);
        }
        return bean; // 可修改Bean实例,这里直接返回原对象
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof MyLifeCycleBean) {
            System.out.println("【7. BeanPostProcessor后置处理】处理Bean:" + beanName);
        }
        return bean;
    }
}

// 3. 配置类(指定init-method和destroy-method)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.example") // 扫描Bean所在包
public class AppConfig {
    @Bean(initMethod = "customInitMethod", destroyMethod = "customDestroyMethod")
    public MyLifeCycleBean myLifeCycleBean() {
        MyLifeCycleBean bean = new MyLifeCycleBean();
        bean.setName("测试Bean"); // 手动设置属性,模拟DI
        return bean;
    }
}

// 4. 测试类(启动容器并关闭,验证生命周期)
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class BeanLifeCycleTest {
    public static void main(String[] args) {
        // 启动Spring容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println("【8. Bean就绪】容器启动完成,Bean可使用");
        
        // 关闭容器,触发Bean销毁
        System.out.println("-------- 开始关闭容器 --------");
        context.close();
    }
}

三、执行结果

【2. 实例化Bean】调用构造方法创建对象
【3. 属性注入】设置name属性:测试Bean
【4. BeanNameAware】设置Bean名称:myLifeCycleBean
【4. BeanFactoryAware】设置BeanFactory:DefaultListableBeanFactory
【4. ApplicationContextAware】设置ApplicationContext:AnnotationConfigApplicationContext
【5. BeanPostProcessor前置处理】处理Bean:myLifeCycleBean
【6. 初始化】执行@PostConstruct注解方法
【6. 初始化】执行InitializingBean接口的afterPropertiesSet方法
【6. 初始化】执行自定义init-method方法
【7. BeanPostProcessor后置处理】处理Bean:myLifeCycleBean
【8. Bean就绪】容器启动完成,Bean可使用
-------- 开始关闭容器 --------
【9. 销毁】执行@PreDestroy注解方法
【9. 销毁】执行DisposableBean接口的destroy方法
【9. 销毁】执行自定义destroy-method方法

四、补充
初始化方法优先级:@PostConstruct > InitializingBean.afterPropertiesSet() > 自定义init-method;
销毁方法优先级:@PreDestroy > DisposableBean.destroy() > 自定义destroy-method;
BeanPostProcessor:是全局扩展点,会作用于容器中所有 Bean(可通过判断 Bean 类型过滤),Spring 的 AOP 就是基于这个接口实现的(后置处理阶段生成代理对象);
懒加载 Bean:默认 Bean 在容器启动时初始化,若设置@Lazy,则第一次获取 Bean 时才执行生命周期;
单例 vs 原型 Bean

  • 单例 Bean:容器启动时创建,容器关闭时销毁(生命周期完整);
  • 原型 Bean:每次获取时创建,容器不管理销毁(销毁阶段的方法不会执行)。
posted @ 2026-01-12 11:43  daring_ding  阅读(85)  评论(0)    收藏  举报