Spring Bean 生命周期详解:从创建到销毁的完整流程

一、生命周期阶段概览

Spring Bean 的生命周期贯穿容器管理全过程,包含以下核心阶段:

二、关键接口与注解
阶段接口注解XML 配置
实例化InstantiationAwareBeanPostProcessor--
属性注入BeanPostProcessor@Autowired<property>
初始化前BeanPostProcessor.postProcessBeforeInitialization--
初始化InitializingBean.afterPropertiesSet@PostConstructinit-method
初始化后BeanPostProcessor.postProcessAfterInitialization--
销毁前DisposableBean.destroy@PreDestroydestroy-method
销毁BeanFactory 关闭时自动触发--
三、生命周期详细流程
  1. 实例化阶段

    // 通过构造函数创建Bean实例
    public class UserService {
        public UserService() {
            System.out.println("UserService实例化");
        }
    }
    
  2. 属性注入阶段

    @Service
    public class OrderService {
        @Autowired
        private UserService userService; // 依赖注入
    }
    
  3. 初始化前处理

    public class CustomBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) {
            if ("userService".equals(beanName)) {
                System.out.println("初始化前处理:" + beanName);
            }
            return bean;
        }
    }
    
  4. 初始化阶段

    @Service
    public class PaymentService implements InitializingBean {
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("PaymentService初始化");
        }
    
        @PostConstruct
        public void init() {
            System.out.println("通过@PostConstruct初始化");
        }
    }
    
  5. 初始化后处理

    public class CustomBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            if ("paymentService".equals(beanName)) {
                System.out.println("初始化后处理:" + beanName);
            }
            return bean;
        }
    }
    
  6. 销毁阶段

    @Service
    public class CacheService implements DisposableBean {
        @Override
        public void destroy() throws Exception {
            System.out.println("CacheService销毁");
        }
    
        @PreDestroy
        public void cleanUp() {
            System.out.println("通过@PreDestroy清理资源");
        }
    }
    
四、容器管理流程

Spring 容器通过refresh()方法启动生命周期管理:

public ConfigurableListableBeanFactory refreshBeanFactory() {
    // 1. 创建BeanFactory
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    
    // 2. 注册BeanPostProcessor
    beanFactory.addBeanPostProcessor(new CustomBeanPostProcessor());
    
    // 3. 实例化所有singleton Bean
    beanFactory.preInstantiateSingletons();
    
    return beanFactory;
}
五、扩展生命周期的方式
  1. BeanPostProcessor

    public class LoggingBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) {
            System.out.println("Bean [" + beanName + "] 初始化前");
            return bean;
        }
    }
    
  2. FactoryBean

    public class DataSourceFactoryBean implements FactoryBean<DataSource> {
        @Override
        public DataSource getObject() throws Exception {
            DataSource dataSource = new HikariDataSource();
            // 初始化数据源
            return dataSource;
        }
    }
    
  3. SmartInitializingSingleton

    public class StartupService implements SmartInitializingSingleton {
        @Override
        public void afterSingletonsInstantiated() {
            System.out.println("所有singleton Bean初始化完成");
        }
    }
    
六、最佳实践建议
  1. 资源管理

    • @PostConstruct中初始化外部资源(数据库连接、线程池等)
    • @PreDestroy中释放资源
  2. 避免循环依赖

    // 错误示例:ServiceA与ServiceB相互依赖
    @Service
    public class ServiceA {
        @Autowired
        private ServiceB serviceB;
    }
    
  3. 代理对象生命周期

    • 当 Bean 被 AOP 代理时,@PostConstruct在代理对象中执行
    • 使用AopContext.currentProxy()获取代理对象
  4. 作用域管理

    • prototype Bean 不会触发销毁方法
    • 使用@RequestScope需配合RequestContextListener
七、常见问题诊断
  1. Bean 未初始化

    • 检查是否遗漏@Component等注解
    • 确认配置类是否被扫描
  2. 销毁方法未执行

    • 确保容器正常关闭(调用close()方法)
    • 非 singleton Bean 需手动管理
  3. 循环依赖排查

    # 使用Spring Boot Actuator查看依赖关系
    curl http://localhost:8080/beans
    
八、总结

掌握 Spring Bean 生命周期有助于:

  • 优化资源初始化与释放
  • 解决依赖注入问题
  • 实现复杂初始化逻辑
  • 诊断容器启动异常

通过合理使用生命周期接口和注解,可以构建更健壮的 Spring 应用。建议结合具体业务场景选择合适的扩展方式,避免过度设计。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值