关于 Spring Bean 的生命周期,网上的分析多不胜数,但大多都是在介绍 BeanPostProcessor 的接口实现以及集成该接口的实现,Spring Bean 的完整生命周期从创建 Spring 容器开始,直到最终 Spring 容器销毁 Bean,这其中包含了一系列关键点。今天我们就 bean 生命周期内的实例化方面来在源码中探索一下它的实现。
前言
前几篇文章 我们了解了 Spring容器的刷新逻辑 ,现在我们继续跟进后续 Spring IOC 容器中 bean 实例化来分析相应源码实现。
概要
bean 的实例化过程与其中的依赖注入的实现的分析
- AbstractBeanFactory
- doGetBean 获取 bean 实例
- DefaultSingletonRegistry
- getSingleton 获取单例实例
- 三级缓存 解决循环依赖
- AbstractAutowireCapableBeanFactory
- createBean 创建 bean 实例的准备
- doCreateBean 创建 bean 实例
- applyMergedBeanDefinitionPostProcessors 处理 @Autowriet 和 @Value
- populateBean 给 bean 实例注入属性值(依赖注入)
分析
获取 bean 实例的源头
在 Spring 容器刷新逻辑最后我们看到了 DefaultListableBeanFactory#preInstantiateSingletons 方法是为了实例化所有剩余的( non-lazy-init 非延时加载的)单例。
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 获取到 beanDefinitionNames 容器里所有的 beanName
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 循环所有的已注册的 beanName
for (String beanName : beanNames) {
// 获取合并后的 beanDefinition,beanDefinition 是可以存在继承关系的,子类中的属性会覆盖父类的属性
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象( xml 配置中是否配置了 abstract 属性,而不是说这个类不是一个抽象类)、单例的、非懒加载的才需要实例化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 处理 factoryBean (&) 的
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 正常普通的 bean 会走到这个流程,这里就把这个bean实例化并且管理起来的
// 这里是获取一个 bean,如果获取不到,则创建一个
getBean(beanName);
}
}
}
// bean 实例化之后,还会有一些处理
// @EventListener 标注的方法被 DefaultEventListenerFactory 包装成 ApplicationListenerMethodAdapter
// @EventListener 中的 classes 就是事件对象
// ApplicationListenerMethodApdapter 注册到 ApplicationContext 中。
// 等待是事件源发布通知,通知后执行的逻辑就是标注 @EventListener 的方法的逻辑
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
那我们自然就走到了 AbstractBeanFactory#getBean 方法内
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
获取 bean 实例
可以看见 getBean 方法调用了 doGetBean,在 Spring 源码里我们会发现许多类似的方法,他们内部的处理都是交给 do* 方法去执行的。我们继续看 doGetBean 方法:
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 通过三种形式获取 beanName
// 一个是原始的 beanName,一个是加了 & 的,一个是别名
final String beanName = transformedBeanName(name);
Object bean;
// 尝试从单例缓存集合里获取 bean 实例
Object sharedInstance = getSingleton(beanName);
// 如果先前已经创建过单例 Bean 的实例,并且调用的 getBean 方法传入的参数为空
// 则执行 if 中逻辑
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
// 如果 Bean 还在创建中,则说明是循环引用
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 如果是普通 bean,直接返回,如果是 FactoryBean,则返回他的 getObject
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 若 scope 为 prototype 或者单例模式但是缓存中还不存在 bean
else {
// 如果 scope 为 prototype 并且显示还在创建中,则基本是循环依赖的情况
// 针对 prototype 的循环依赖,直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
// 从当前容器中找不到指定名称的 bean,此时递归去 parentFactory 查找
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 主要针对 FactoryBean,将 Bean 的 & 重新加上
String nameToLookup = originalBeanName(name);
// 如果 parent 容器依旧是 AbstractBeanFactory 的实例
// instanceof 通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 直接递归调用方法来查找
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 如果有参数,则委派父级容器根据指定名称和显式的参数查找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// 委派父级容器根据指定名称和类型查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 委派父级容器根据指定名称查找
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// typeCheckOnly 是用来判断调用 getBean() 是否仅仅是为了类型检查获取 bean,而不是为了创建Bean
if (!typeCheckOnly) {
// 如果不是仅仅做类型检查则是创建 bean
markBeanAsCreated(beanName);
}
try {
// 将父类的 BeanDefinition 与子类的 BeanDefinition 进行合并覆盖
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 对合并的 BeanDefinition 做验证,主要看属性是否为 abstract 的
checkMergedBeanDefinition(mbd, beanName, args);
// 获取当前Bean所有依赖Bean的名称
String[] dependsOn = mbd.getDependsOn();
// 如果当前Bean设置了dependsOn的属性
// depends-on用来指定Bean初始化及销毁时的顺序
if (dependsOn != null) {
for (String dep : dependsOn) {
// 校验该依赖是否已经注册给当前 bean,注意这里传入的key是当前的bean名称
// 这里主要是判断是否有以下这种类型的依赖:
// 如果有,则直接抛出异常
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 缓存依赖调用,注意这里传入的key是被依赖的bean名称
registerDependentBean(dep, beanName);
try {
// 递归调用getBean方法,注册Bean之间的依赖(如C需要晚于B初始化,而B需要晚于A初始化)
// 初始化依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 如果 BeanDefinition 为单例
if (mbd.isSingleton()) {
// 这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 显式从单例缓存中删除 bean 实例
// 因为单例模式下为了解决循环依赖,可能它已经存在了,所以将其销毁
destroySingleton(beanName);
throw ex;
}
});
// 如果是普通bean,直接返回,是FactoryBean,返回他的getObject
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// Prototype 每次都会创建一个新的对象
Object prototypeInstance = null;
try {
// 默认的功能是注册当前创建的 prototype 对象为正在创建中
beforePrototypeCreation(beanName);
// 创建原型对象实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 默认的功能是将先前注册的正在创建中的 Bean 信息给抹除掉
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 要创建的 Bean 既不是单态模式,也不是原型模式,则根据 Bean 定义资源中
// 配置的生命周期范围,选择实例化 Bean 的合适方法,这种在Web应用程序中
// 比较常用,如:request、session、application 等生命周期
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
// Bean 定义资源中没有配置生命周期范围,则Bean定义不合法
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 对创建的 Bean 实例对象进行类型检查
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
可以看到 doGetBean 方法内逻辑很多,主要是获取或创建 bean 实例,再对 bean 实例进行类型检查。大概可以分为七步:
- 尝试从缓存中获取 bean 实例
- 三级缓存的实现
- 循环依赖的判断
- 循环依赖的例子:B 含 @Autowired A, A 含 @Autowired B ,A B 循环依赖
- 递归去父容器中获取 bean 实例
- 从当前容器获取 BeanDefinition 实例
- 递归实例化显式依赖的 bean
- 根据不同的 scope 采用不用的策略创建 bean 实例
- 对 bean 实例进行类型检查
下面 我们根据 doGetBean 方法内的步骤一一讲解
获取 bean 实例的三级缓存
从 doGetBean 方法我们跟进到从单例缓存集合里获取 bean 实例,即 DefaultSingletonBeanRegistry#getSingleton 方法,源码如下:
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//尝试从一级缓存里面获取完备的 Bean
Object singletonObject = this.singletonObjects.get(beanName);
//如果完备的单例还没有创建出来,创建中的 Bean 的名字会被保存在 singletonsCurrentlyInCreation 中
//因此看看是否正在创建
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//尝试给一级缓存对象加锁,因为接下来就要对缓存对象操作了
synchronized (this.singletonObjects) {
//尝试从二级缓存 earlySingletonObjects 这个存储还没进行属性添加操作的 Bean 实例缓存中获取
singletonObject = this.earlySingletonObjects.get(beanName);
//如果还没有获取到并且第二个参数为true,为true则表示bean允许被循环引用
if (singletonObject == null && allowEarlyReference) {
//从三级缓存 singletonFactories 这个 ObjectFactory 实例的缓存里尝试获取创建此 Bean 的单例工厂实例
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
//如果获取到工厂实例
if (singletonFactory != null) {
//调用单例工厂的 getObject 方法返回对象实例
singletonObject = singletonFactory.getObject();
//将实例放入二级缓存里
this.earlySingletonObjects.put(beanName, singletonObject);
//从三级缓存里移除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
在 DefaultSingletonBeanRegistry 这个类中我们可以看到这三个缓存的 map
// 一级缓存:单例对象缓存池,beanName->Bean,其中存储的就是实例化,属性赋值成功之后的单例对象
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 三级缓存:单例工厂的缓存,beanName->ObjectFactory,添加进去的时候实例还未具备属性
// 用于保存 beanName 和创建 bean 的工厂之间的关系 map,单例Bean在创建之初过早的暴露出去的 Factory,
// 为什么采用工厂方式,是因为有些Bean是需要被代理的,总不能把代理前的暴露出去那就毫无意义了
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 二级缓存:早期的单例对象,beanName->Bean,其中存储的是实例化之后,属性未赋值的单例对象
// 执行了工厂方法生产出来的 Bean,bean 被放进去之后,
// 那么当 bean 在创建过程中,就可以通过 getBean 方法获取到
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
从缓存中获取 bean 实例主要就是在对这三个 map 缓存做相应的处理
递归去父容器中获取 bean 实例
从当前容器中找不到指定名称的 bean,此时递归去 parentFactory 查找
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 主要针对 FactoryBean,将 Bean 的 & 重新加上
String nameToLookup = originalBeanName(name);
// 如果 parent 容器依旧是 AbstractBeanFactory 的实例
// instanceof 通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 直接递归调用方法来查找
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 如果有参数,则委派父级容器根据指定名称和显式的参数查找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// 委派父级容器根据指定名称和类型查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 委派父级容器根据指定名称查找
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
从当前容器获取 BeanDefinition 实例
在 getMergedLocalBeanDefinition 方法中主要将父类的 BeanDefinition 与子类的 BeanDefinition 进行合并覆盖,在 checkMergedBeanDefinition 方法中主要是对合并的 BeanDefinition 做验证,主要看属性是否为 abstract 的
// 返回合并的 BeanDefinition,如果指定的 bean 对应于子 BeanDefinition,则遍历父 BeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
// 遍历父 BeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
// 检查给定的合并 bean 定义,可能抛出验证异常。
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
throws BeanDefinitionStoreException {
if (mbd.isAbstract()) {
throw new BeanIsAbstractException(beanName);
}
}
递归实例化显式依赖的 bean
在这要注意 Spring 中不支持显式定义依赖的 例如:如果有 直接抛出异常信息
<bean id="beanA" class="BeanA" depends-on="beanB">
<bean id="beanB" class="BeanB" depends-on="beanA">
在代码中可见:在递归调用getBean方法,来注册Bean之间的依赖。
// 缓存依赖调用,注意这里传入的key是被依赖的bean名称
registerDependentBean(dep, beanName);
try {
// 递归调用getBean方法,注册Bean之间的依赖(如C需要晚于B初始化,而B需要晚于A初始化)
// 初始化依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
根据不同的 scope 采用不用的策略创建 bean 实例
这里主要是针对 scope 的不同来使用不同的 createBean 方法
scope 为 instance 时,这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 显式从单例缓存中删除 bean 实例
// 因为单例模式下为了解决循环依赖,可能它已经存在了,所以将其销毁
destroySingleton(beanName);
throw ex;
}
});
我们看看这个 getSingleton 方法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 先从 singletonObjects 通过 beanName 获取 bean 实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 如果 spring 单例 bean 容器正在销毁时不允许继续创建单例 bean
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 这里就是调用传进来的 lamdba 方法,也就是调用了 createBean 方法创建了 bean 实例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
// ··· catch
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 从正在创建的 beanNameSet 移除
afterSingletonCreation(beanName);
}
// 如果成功创建了 bean 实例,需要加入 singletonObjects 容器
// 这样下次再获取就能直接中容器中获取
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
// Bean实例完成创建之后,只保留一级缓存以及注册 beanName 的顺序,其余的清除
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
// 往三级缓存里添加
this.singletonFactories.put(beanName, singletonFactory);
// 清除此 Bean 在二级缓存里的缓存信息
this.earlySingletonObjects.remove(beanName);
// 这里为了记录注册单例的顺序
this.registeredSingletons.add(beanName);
}
}
}
对 bean 实例进行类型检查
对创建的 Bean 实例对象看一看有没有必要进行类型检查,没有就直接返回 bean 实例了。
之前在 doGetBean 方法我们可以看到真正的 bean 初始化逻辑方法:AbstractAutowireCapableBeanFactory#createBean
bean 初始化逻辑方法 createBean
之所以说 createBean 方法是真正的 bean 初始化逻辑,因为它不仅仅是创建一个 bean 实例,还涉及到一些校验方法,以及类里的依赖注入、初始化方法调用等逻辑,现在我们就简单看一下,之后会详细写一篇文章介绍:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
··· logger
//判断需要创建的 Bean 是否可以实例化,即是否可以通过当前的类加载器加载
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 克隆一份 BeanDefinition,用来设置上加载出来的 class 对象
// 之所以后续用该副本操作,是因为不希望将解析的 class 绑定到缓存里的 BeanDefinition
// 因为 class 有可能是每次都需要动态解析出来的
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//校验和准备, Bean 中方法的覆盖
···
try {
//创建Bean的入口
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
// 异常处理
···
}
可以看到,createBean 主要是校验和准备环境,并没有去真正的创建 bean 的实例,而是交给 doCreateBean 方法,这与 getBean 方法调用了 doGetBean 方法类似。
现在我们知道,doCreateBean 是我们 spring 真正的实例化 bean 的方法:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// bean 实例包装类
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 从未完成创建的包装 Bean 缓存中清理并获取相关中的包装 Bean 实例,毕竟是单例的,只能存一份
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 这里创建 bean 的实例有三种方法
// 1.工厂方法创建
// 2.构造方法的方式注入
// 3.无参构造方法注入
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获取被包装的 Bean,后续对 bean 的改动相当于对 Wrapper 的改动,反之依然
final Object bean = instanceWrapper.getWrappedInstance();
// 获取实例化对象的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 调用 BeanDefinition 属性合并完成后的 BeanPostProcessor 后置处理器
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//被 @Autowired、@Value 标记的属性在这里获取
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
// 异常处理 ···
mbd.postProcessed = true;
}
}
// 向容器中缓存单例模式的 Bean 对象,以防循环引用
// 判断是否是早期引用的 bean,如果是,则允许其提前暴露引用
// 这里判断的逻辑主要有三个:
// 1.是否为单例
// 2.是否允许循环引用
// 3.是否是在创建中的 bean
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// logger
// 这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Bean 对象的初始化,依赖注入在此触发
// 这个 exposedObject 在初始化完成之后返回作为依赖注入完成后的 Bean
Object exposedObject = bean;
try {
// 填充 bean 实例的属性
populateBean(beanName, mbd, instanceWrapper);
// 初始化 bean,过程如下:
// 1:判断是否实现了BeanNameAware,BeanClassLoaderAware,
// BeanFactoryAware方法,如果有,则设置相关的属性
// 2: 调用 bean 初始化的前置(BeanPostProcessor)操作
// 3: 执行初始化的方法。
// 如果有 initializingBean,则调用 afterPropertiesSet
// 如果有 InitMethod,则调用初始方法
// 4: 调用 bean 初始化的后置(BeanPostProcessor)操作
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
// 异常处理 ···
// 若允许循环依赖,则解决相关的循环依赖
if (earlySingletonExposure) {
//获取指定名称的已注册的单例模式Bean对象
Object earlySingletonReference = getSingleton(beanName, false);
// ···
}
try {
//注册 Bean 的销毁逻辑
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
// 异常处理 ···
return exposedObject;
}
可以看到,doCreateBean 大致做了5件事:
- 创建 bean 实例: createBeanInstance
- 调用 BeanDefinition 属性合并完成后的 BeanPostProcessor 后置处理器
- 填充 bean 实例的属性:populateBean
- 调用 bean 的初始化方法:initializeBean
- 注册 bean 的销毁逻辑: registerDisposableBeanIfNecessary
这几个方法我单独出一篇文章单独详细讲解 doCreateBean 方法。详情可见 Spring 源码解析(五)深入探索 bean 的实例化 -- doCreateBean 方法的解析
本文基于 spring-framework 5.2.10.RELEASE 版本进行分析