跳转到内容

Spring Bean生命周期

来自代码酷


概述[编辑 | 编辑源代码]

Spring Bean生命周期是指从Bean的实例化到销毁的完整过程,由Spring IoC容器管理。理解生命周期对控制Bean行为、资源管理和扩展框架功能至关重要。Spring提供了多种机制(接口、注解、配置)允许开发者介入生命周期的各个阶段。

核心阶段[编辑 | 编辑源代码]

Spring Bean生命周期可分为以下主要阶段(按执行顺序):

1. 实例化[编辑 | 编辑源代码]

容器通过构造器或工厂方法创建Bean实例。此时对象处于"原始状态",依赖未注入。

2. 属性赋值[编辑 | 编辑源代码]

容器通过setter或字段注入完成依赖注入(DI)。若存在循环依赖,Spring会使用三级缓存解决。

3. 初始化[编辑 | 编辑源代码]

  • BeanNameAware:设置Bean的ID
  • BeanFactoryAware:设置所属BeanFactory
  • ApplicationContextAware:设置所属ApplicationContext(需注意与BeanFactory的区别)
  • @PostConstruct:注解标记的初始化方法
  • InitializingBean:实现afterPropertiesSet()方法
  • 自定义init-method:XML或@Bean(initMethod="...")指定的方法

4. 使用期[编辑 | 编辑源代码]

Bean处于就绪状态,可被应用程序使用。

5. 销毁[编辑 | 编辑源代码]

  • @PreDestroy:注解标记的销毁方法
  • DisposableBean:实现destroy()方法
  • 自定义destroy-method:XML或@Bean(destroyMethod="...")指定的方法

生命周期流程图[编辑 | 编辑源代码]

graph TD A[实例化] --> B[属性赋值] B --> C[BeanNameAware] C --> D[BeanFactoryAware] D --> E[ApplicationContextAware] E --> F[@PostConstruct] F --> G[InitializingBean] G --> H[init-method] H --> I[使用期] I --> J[@PreDestroy] J --> K[DisposableBean] K --> L[destroy-method]

代码示例[编辑 | 编辑源代码]

完整生命周期示例[编辑 | 编辑源代码]

public class LifecycleDemo implements BeanNameAware, BeanFactoryAware, 
        ApplicationContextAware, InitializingBean, DisposableBean {
    
    private String dependency;

    // 1. 构造器
    public LifecycleDemo() {
        System.out.println("1. 构造器调用");
    }

    // 2. 属性注入
    public void setDependency(String dependency) {
        this.dependency = dependency;
        System.out.println("2. 依赖注入: " + dependency);
    }

    // 3. BeanNameAware
    @Override
    public void setBeanName(String name) {
        System.out.println("3. BeanNameAware: " + name);
    }

    // 4. BeanFactoryAware
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        System.out.println("4. BeanFactoryAware");
    }

    // 5. ApplicationContextAware
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        System.out.println("5. ApplicationContextAware");
    }

    // 6. @PostConstruct
    @PostConstruct
    public void postConstruct() {
        System.out.println("6. @PostConstruct");
    }

    // 7. InitializingBean
    @Override
    public void afterPropertiesSet() {
        System.out.println("7. InitializingBean.afterPropertiesSet()");
    }

    // 8. 自定义init
    public void customInit() {
        System.out.println("8. 自定义init-method");
    }

    // 9. @PreDestroy
    @PreDestroy
    public void preDestroy() {
        System.out.println("9. @PreDestroy");
    }

    // 10. DisposableBean
    @Override
    public void destroy() {
        System.out.println("10. DisposableBean.destroy()");
    }

    // 11. 自定义destroy
    public void customDestroy() {
        System.out.println("11. 自定义destroy-method");
    }
}

配置示例[编辑 | 编辑源代码]

<!-- XML配置方式 -->
<bean id="lifecycleDemo" class="com.example.LifecycleDemo"
      init-method="customInit" destroy-method="customDestroy">
    <property name="dependency" value="示例依赖"/>
</bean>
// Java配置方式
@Configuration
public class AppConfig {
    @Bean(initMethod = "customInit", destroyMethod = "customDestroy")
    public LifecycleDemo lifecycleDemo() {
        LifecycleDemo demo = new LifecycleDemo();
        demo.setDependency("示例依赖");
        return demo;
    }
}

实际应用场景[编辑 | 编辑源代码]

数据库连接池管理[编辑 | 编辑源代码]

1. 初始化阶段:创建连接池、预建立连接 2. 使用阶段:提供数据库连接 3. 销毁阶段:关闭所有连接释放资源

缓存预热[编辑 | 编辑源代码]

通过@PostConstruct在启动时加载热点数据:

@Service
public class CacheService {
    private Map<String, Object> cache = new ConcurrentHashMap<>();

    @PostConstruct
    public void warmUpCache() {
        // 从数据库加载热点数据
        cache.put("hotProduct", productRepository.findTopSelling());
    }
}

高级主题[编辑 | 编辑源代码]

生命周期处理器[编辑 | 编辑源代码]

实现BeanPostProcessor可拦截所有Bean的初始化过程:

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

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("处理初始化后: " + beanName);
        return bean;
    }
}

作用域的影响[编辑 | 编辑源代码]

不同作用域的Bean生命周期表现:

  • singleton:容器启动时创建(可配置延迟初始化),容器关闭时销毁
  • prototype:每次请求时创建,容器不管理其销毁
  • request/session:对应HTTP请求/会话周期

数学表示单例Bean的生命周期: Tlifecycle=[tcreate,tdestroy],tcreate{tstartup,tfirstRequest}

常见问题[编辑 | 编辑源代码]

Q:初始化方法的执行顺序是什么? A:严格顺序:@PostConstruct → InitializingBean → init-method

Q:如何选择初始化方式? A:推荐优先级:

  1. @PostConstruct(无框架耦合)
  2. init-method(XML配置友好)
  3. InitializingBean(需实现接口)

Q:prototype Bean的@PreDestroy为何不生效? A:Spring不管理prototype Bean的完整生命周期,需通过@Bean的destroyMethod或手动调用销毁方法

最佳实践[编辑 | 编辑源代码]

1. 单一职责:每个生命周期方法只做一件事 2. 避免耗时操作:初始化方法应快速完成 3. 防御式编程:检查依赖项是否注入 4. 文档记录:明确记录自定义生命周期方法的作用