了解专栏完整的内容,请点击跳转:
Spring framework专栏导航页
上一篇文章,我门已经了解了Spring容器初始化的过程。初始化过程中会将单例、非抽象的、非懒加载的Bean创建好并放进缓存中以供使用。Bean的生命周期也就是指创建、使用、销毁的全过程,下面就此展开。
流程图点击查看
Bean的生命周期
大白话概述一下Bean的创建:
我们知道对象(即Bean)的创建一般使用new或者反射的方式创建,Spring就是采用反射的方式来创建Bean。Spring Bean的创建包括了实例化、属性赋值、初始化,经过以上三步就能完成Bean的创建。但Spring既然是框架,就要给使用者多提供一些拓展点,让用户扩展,所以在Bean的生命周期中,会有9个BeanPostProcessor以及一些可以拓展的接口。
这些后置处理器干嘛用的?说白了就是每个Bean创建时候都去遍历一下当前的后置处理器,看是否需要被处理一下。遍历的时机也是有好几处。
有了拓展点以外,还有一个棘手的问题就是Bean间循环依赖(A依赖B,B依赖A)的问题,以及循环依赖下AOP(需要创建代理对象,并把代理对象赋值给被依赖Bean)。为了解决这个问题,Spring是借助一、二、三级缓存和后置处理器来实现的,循环依赖的具体细节将在下一篇文章阐述。
实例化前
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
//判断容器中是否有InstantiationAwareBeanPostProcessors
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
// 一般情况下返回的都是null
// 如果不为null说明生成了代理对象那么我们就调用
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
实例化
if (instanceWrapper == null) {
// 实例化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
@Autowired预处理
try {
// 第3个bean后置处理器
// 进行后置处理 @AutoWired @Value的注解的预解析
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
实例化后的Bean放三级缓存
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
//上述条件满足,允许早期暴露对象
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//把我们的早期对象包装成一个singletonFactory对象 该对象提供了一个getObject方法,
// 该方法内部调用getEarlyBeanReference方法,该方法再去调后置处理器
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
填充属性
// 填充属性 populateBean(beanName, mbd, instanceWrapper);
初始化
// aware方法、初始化前、初始化、 初始化后 exposedObject = initializeBean(beanName, exposedObject, mbd);
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
销毁
@Override
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// If we registered a JVM shutdown hook, we don't need it anymore now:
// We've already explicitly closed the context.
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
@PostConstruct
最后提一点。很多人觉得这个注解标记的方法,是在Bean初始化阶段的invokeInitMethods(beanName, wrappedBean, mbd);里边执行的,
其实是在初始化阶段的applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);执行的



