Spring框架管理的bean具有一个复杂的生命周期,涉及多个阶段和回调接口。了解这个生命周期是关键,它能帮助您在正确的时间点进行自定义逻辑的注入。
Bean instantiation
): 通过构造函数创建bean实例。Populate properties
): Spring IoC容器注入属性值。Set Bean Name
): 如果bean实现了BeanNameAware
接口,Spring将bean的ID传递给setBeanName()
方法。Set Bean Factory
): 如果bean实现了BeanFactoryAware
接口,Spring将调用setBeanFactory()
方法,传入Spring工厂自身。Set Application Context
): 如果bean实现了ApplicationContextAware
接口,setApplicationContext()
方法将被调用,传入bean所属的应用上下文。Bean Post-Processing before initialization
): 如果BeanPostProcessor与bean关联,postProcessBeforeInitialization()
将被调用。Initialization
): 如果bean实现了InitializingBean
接口,afterPropertiesSet()
方法将被调用。同样,如果bean定义了init-method
,指定的方法也会被调用。Bean Post-Processing after initialization
): 如果BeanPostProcessor与bean关联,postProcessAfterInitialization()
将被调用。Use bean
): 此时,bean是准备好的,可以被应用程序使用了。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-method
和destroy-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。