Spring作为当前Java最流行、最强大的轻量级框架。深入的了解Spring Bean的生命周期是非常必要的。我们通常把ApplicationContext作为Spring容器。所以,我们讲的也是ApplicationContext容器中Bean的生命周期。
在Spring中,其实有一个类完完整整的描述了Spring Bean的生命周期。让我们来看这个类
一:Spring Bean的生命周期流程图。
二:Spring Bean的生命周期主要有这四个阶段:
1. 实例化 createBeanInstance
2. 属性赋值 populateBean
3. 初始化 initializeBean
4. 销毁 destroyBean
实例化 -> 属性赋值 -> 初始化 -> 销毁
整个Spring Bean的生命周期逻辑都在doCreateBean()方法中。逻辑清晰,按顺序调用。
三:下面看源码:
1. doCreateBean方法的源码
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
/**
* 创建 bean 实例,并将实例包裹在 BeanWrapper 实现类对象中返回。
* createBeanInstance中包含三种创建 bean 实例的方式:
* 1. 通过工厂方法创建 bean 实例
* 2. 通过构造方法自动注入(autowire by constructor)的方式创建 bean 实例
* 3. 通过无参构造方法方法创建 bean 实例
*
* 若 bean 的配置信息中配置了 lookup-method 和 replace-method,则会使用 CGLIB 增强 bean 实例。
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//BeanPostProcessor的运用2:扫描注解
//扫描类的属性、方法上是否有@PostConstruct@PreDestroy @Resource@Autowired @Value注解
//CommonAnnotationBeanPostProcessor -> @PostConstruct @PreDestroy @Resource
//AutowiredAnnotationBeanPostProcessor -> @Autowired @Value
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//提前暴露bean对象,放入三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//初始化Bean对象:属性依赖注入
populateBean(beanName, mbd, instanceWrapper);
//初始化bean对象:调用初始化方法等...
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
// Register bean as disposable.
//注册销毁方法:最终会被ContextLoaderListener的contextDestroyed方法调用
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
2.实例化整个流程
2.1)调用createBeanInstance方法通过BeanDefinition信息实例化Bean对象:
2.2)主要用来收集构造器信息,用于反射实例化:
2.3)继续往下看:
2.4)真正的反射实例化对象,先开启权限可以访问,在调用ctor.newInstance(args)方法创建对象。
3.属性赋值整个流程
3.1)调用populateBean完成属性赋值(属性的依赖注入):
3.2)调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法完成属性赋值,这里主要看AutowiredAnnotationBeanPostProcessor实现类:
3.3)通过属性、方法上有@Autowired@Resource@Value注解的进入依赖注入:
3.4)属性的依赖注入:
首先拿到属性:Field field = (Field) this.member,
然后从SpringIOC容器中获取属性的值:value = beanFactory.resolveDependency();
最后完成属性的赋值:field.set(bean, value)
3.5)方法的依赖注入:
首先拿到方法:Method method = (Method) this.member;
然后完成方法的参数封装:
最后完成方法的调用:method.invoke(bean, arguments);
4.初始化整个流程
4.1)初始化入口:
4.2)完成初始化功能:
完成Aware接口的调用;
完成BeanPostProcessor.postProcessBeforeInitialization方法调用;
完成初始化方法的调用;完成自定义初始化方法的调用;
完成BeanPostProcessor.postProcessAfterInitialization方法调用;
5.销毁整个流程
Bean的销毁整个流程比较复杂:
5.1)注册销毁方法;
5.2)调用注册的销毁方法。
什么时候销毁? 由谁调用销毁方法?是我们的SpringIOC容器吗?
首先肯定不是我们的SpringIOC容器调用销毁。也只有我们的Servlet容器关闭后需要销毁;也只有servlet容器有权利调用销毁方法。
5.3)看一下注册销毁:注册销毁方法是在我们的Bean创建完成后完成注册的;
5.3.1) 注册销毁的入口;
5.3.2)把销毁方法包装成了DisposableBeanAdapter;
5.3.3)包装后的对象放入属性disposableBeans容器中。
5.4)看一下调用销毁方法:调用销毁方法是我们的servlet容器;
5.4.1)servlet容器关闭后调用spring容器销毁;
5.4.2)最终会调到这个方法;完成属性的移除、销毁方法的调用。
到此. Spring Bean的生命周期介绍结束,请看下一章.