Spring bean生命周期

Spring框架管理的bean具有一个复杂的生命周期,涉及多个阶段和回调接口。了解这个生命周期是关键,它能帮助您在正确的时间点进行自定义逻辑的注入。

Spring Bean生命周期的关键阶段

  1. 实例化 (Bean instantiation): 通过构造函数创建bean实例。
  2. 属性赋值 (Populate properties): Spring IoC容器注入属性值。
  3. Bean名称赋值 (Set Bean Name): 如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()方法。
  4. Bean工厂赋值 (Set Bean Factory): 如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,传入Spring工厂自身。
  5. ApplicationContext赋值 (Set Application Context): 如果bean实现了ApplicationContextAware接口,setApplicationContext()方法将被调用,传入bean所属的应用上下文。
  6. 前处理 (Bean Post-Processing before initialization): 如果BeanPostProcessor与bean关联,postProcessBeforeInitialization()将被调用。
  7. 初始化 (Initialization): 如果bean实现了InitializingBean接口,afterPropertiesSet()方法将被调用。同样,如果bean定义了init-method,指定的方法也会被调用。
  8. 后处理 (Bean Post-Processing after initialization): 如果BeanPostProcessor与bean关联,postProcessAfterInitialization()将被调用。
  9. 使用bean (Use bean): 此时,bean是准备好的,可以被应用程序使用了。
  10. 销毁 (Bean destruction): 当容器关闭时,如果bean实现了DisposableBean接口,destroy()方法将被调用。同样,如果bean定义了destroy-method,指定的方法也会被调用。

源码解析

让我们通过Spring框架的源码来跟踪bean的初始化过程,这个过程主要发生在AbstractAutowireCapableBeanFactory类中。

实例化

createBean()方法中,bean首先被实例化。

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 实例化bean
    Object beanInstance = doCreateBean(beanName, mbd, args);
    // ...
    return beanInstance;
}
属性赋值

一旦实例化完成,Spring会填充bean的所有属性。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
    // 实例化bean
    BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
    final Object bean = instanceWrapper.getWrappedInstance();
    
    // 属性填充
    populateBean(beanName, mbd, instanceWrapper);
    // ...
}
初始化

接下来,如果bean支持InitializingBean接口或定义了init-method,相应的方法将被调用。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    // 前处理
    Object wrappedBean = bean;
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

    // 调用初始化方法
    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null), beanName, "Initialization of bean failed", ex);
    }

    // 后处理
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    return wrappedBean;
}
销毁

当ApplicationContext被关闭时,beans会被销毁。如果bean实现了DisposableBean接口或定义了destroy-method,相应的方法将被调用。

public void destroyBean(final String beanName, final Object bean) {
    // 销毁方法调用
    ((DisposableBean)bean).destroy();
    // 或调用自定义销毁方法
    invokeCustomDestroyMethod(beanName, bean, mbd);
}

代码演示

假设我们有一个简单的bean,它实现了所有的生命周期回调接口:

public class LifeCycleDemoBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware {

    @Override
    public void setBeanName(String name) {
        System.out.println("Phase 1: Bean name is: " + name);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        System.out.println("Phase 2: Bean factory set");
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("Phase 5: Properties set");
    }

    @Override
    public void destroy() {
        System.out.println("Phase 10: Destroying bean");
    }

    public void customInit() {
        System.out.println("Phase 7: Custom init method");
    }

    public void customDestroy() {
        System.out.println("Phase 10: Custom destroy method");
    }
}

并且,我们在Spring配置文件中定义了这个bean,指定了init-methoddestroy-method

<bean id="lifeCycleDemoBean" class="com.example.LifeCycleDemoBean" init-method="customInit" destroy-method="customDestroy"/>

当ApplicationContext启动或关闭时,我们可以看到所有的生命周期方法被按顺序调用。

总结

Spring Bean生命周期包含创建、属性赋值、初始化和销毁过程,在这些阶段可以插入自定义逻辑。Spring Framework提供了多个扩展点(如BeanPostProcessor, InitializingBean, DisposableBean)来自定义和影响bean的生命周期处理过程。深入了解这些原理能够帮助开发者更好地控制和使用Spring容器管理的bean。

你可能感兴趣的:(spring,java,数据库)