Spring Bean生命周期

133 阅读3分钟

Spring Bean的生命周期涵盖实例化、属性注入、初始化(Aware接口、BeanPostProcessor、@PostConstruct)、使用及销毁(@PreDestroy、DisposableBean),通过扩展点实现自定义控制。


Spring Bean生命周期详解

Spring Bean的生命周期是IOC容器管理的核心流程,从Bean的创建、初始化到销毁,每个阶段均提供扩展点供开发者干预。以下是详细的生命周期阶段及关键流程:


一、Bean生命周期阶段

  1. 实例化(Instantiation)

    • 触发时机:容器根据BeanDefinition创建Bean实例(构造函数或工厂方法)。

    • 关键类

      • AbstractAutowireCapableBeanFactory.createBeanInstance():通过反射调用构造函数。
      • FactoryBean.getObject():若Bean实现FactoryBean接口,由其工厂方法生成实例。
  2. 属性填充(Population)

    • 依赖注入:通过Setter、构造器或字段注入(@Autowired@Resource)。

    • 关键方法

      • AbstractAutowireCapableBeanFactory.populateBean():处理属性赋值和依赖解析。
  3. Aware接口回调

    • 感知容器信息

      • BeanNameAware.setBeanName(String name):注入Bean名称。
      • BeanFactoryAware.setBeanFactory(BeanFactory beanFactory):注入BeanFactory。
      • ApplicationContextAware.setApplicationContext(ApplicationContext context):注入ApplicationContext。
    • 触发顺序:在属性注入后、初始化前执行。

  4. BeanPostProcessor前置处理

    • 干预初始化前逻辑

      • BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName):如处理@PostConstruct注解。
    • 典型应用

      • InitDestroyAnnotationBeanPostProcessor:解析@PostConstruct@PreDestroy
      • AutowiredAnnotationBeanPostProcessor:完成依赖注入。
  5. 初始化(Initialization)

    • 初始化方法执行

      • 注解驱动@PostConstruct标注的方法。
      • 接口实现InitializingBean.afterPropertiesSet()
      • XML/Java配置init-method指定的自定义方法。
    • 执行顺序@PostConstructafterPropertiesSet()init-method

  6. BeanPostProcessor后置处理

    • 生成代理对象或增强逻辑

      • BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)
    • 典型应用

      • AOP代理生成(如AnnotationAwareAspectJAutoProxyCreator)。
      • 事务管理的动态代理。
  7. 使用阶段(In Use)

    • 业务逻辑执行:Bean通过容器或直接注入被调用。

    • 作用域影响

      • 单例(Singleton) :容器存活期间唯一实例。
      • 原型(Prototype) :每次请求生成新实例,容器不管理其销毁。
      • Web作用域(Request/Session):生命周期与HTTP请求/会话绑定。
  8. 销毁(Destruction)

    • 销毁方法执行

      • 注解驱动@PreDestroy标注的方法。
      • 接口实现DisposableBean.destroy()
      • XML/Java配置destroy-method指定的自定义方法。
    • 触发条件:容器关闭(ApplicationContext.close()或注册关闭钩子)。

    • 执行顺序@PreDestroydestroy()destroy-method


二、生命周期扩展点

扩展点作用典型实现
BeanPostProcessor干预Bean初始化前后的逻辑(如代理生成)。AutowiredAnnotationBeanPostProcessor
BeanFactoryPostProcessor修改Bean定义(如占位符替换)。PropertySourcesPlaceholderConfigurer
Aware接口让Bean感知容器基础设施。ApplicationContextAwareBeanNameAware
@PostConstruct/@PreDestroy声明初始化/销毁方法。标注自定义生命周期方法。

三、生命周期流程图解

容器启动 → 实例化Bean → 属性注入 → Aware回调 → BeanPostProcessor前置处理 → 
初始化(@PostConstruct → afterPropertiesSet → init-method) → 
BeanPostProcessor后置处理 → 使用阶段 → 容器关闭 → 
销毁(@PreDestroy → destroy() → destroy-method

四、示例代码

  1. 定义生命周期方法

    @Component
    public class OrderService implements InitializingBean, DisposableBean, BeanNameAware {
        private String beanName;
        
        @PostConstruct
        public void customInit() {
            System.out.println("执行@PostConstruct方法");
        }
        
        @Override
        public void afterPropertiesSet() {
            System.out.println("执行InitializingBean.afterPropertiesSet()");
        }
        
        @PreDestroy
        public void customDestroy() {
            System.out.println("执行@PreDestroy方法");
        }
        
        @Override
        public void destroy() {
            System.out.println("执行DisposableBean.destroy()");
        }
        
        @Override
        public void setBeanName(String name) {
            this.beanName = name;
            System.out.println("注入Bean名称:" + name);
        }
    }
    
  2. 配置init/destroy方法(XML)

    <bean id="userService" class="com.example.UserService" 
          init-method="init" 
          destroy-method="cleanup"/>
    

五、注意事项

  1. 作用域与生命周期

    • 原型Bean的销毁方法需手动调用(如通过ConfigurableBeanFactory.destroyBean())。
    • Web作用域Bean由子容器(如RequestContextListener)管理销毁。
  2. 循环依赖限制

    • 构造器注入的循环依赖无法解决,需改用Setter/字段注入。
  3. 性能优化

    • 避免在初始化阶段执行耗时操作(如远程调用),可结合@Lazy延迟加载。

总结:Spring Bean的生命周期通过标准化阶段和扩展接口,实现了从创建到销毁的精细控制。开发者可通过BeanPostProcessor、Aware接口及生命周期注解,灵活定制Bean的初始化与销毁逻辑,适应复杂业务需求。