Spring Bean 默认在单例的情况下支持循环依赖(属性注入)。如下代码启动执行不会异常:
@Configuration
@ComponentScan("com.alex.space")
public class AppConfig {
}
@Component
public class A {
@Autowired
B b;
public A() {
System.out.println("constructor from A");
}
}
@Component
public class B {
@Autowired
A a;
public B() {
System.out.println("constructor from B");
}
}
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
System.out.println("========");
System.out.println(ctx.getBean(A.class));
System.out.println(ctx.getBean(B.class));
}
复制代码
输出结果
constructor from A
constructor from B
========
com.alex.space.A@247bddad
com.alex.space.B@d35dea7
复制代码
如果要关闭循环依赖
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.setAllowCircularReferences(false);
// 为什么要这么写?可以看 AnnotationConfigApplicationContext 的构造方法
ctx.register(AppConfig.class);
ctx.refresh();
// 会出现如下异常
// Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
复制代码
要了解 Spring 是如何解决循环依赖的问题,先要了解 Spring Bean 的构造过程以及生命周期。
Spring Bean 生命周期
Spring 容器创建后初始化的的大概描述,包括容器的创建:
实例化 ApplicationContext
注册配置类,解析配置类的 BeanDefinition 加入 BeanDefinitionMap
完成 Bean 的扫描,解析所有 BeanDefinition,加入 BeanDefinitionMap
实例化 Bean 流程
Spring 容器的初始化以及 Bean 的实例化/自动注入是在上面例子中的 register()
和 refresh()
方法中完成的
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
// 【1】实例化 ApplicationContext,创建 BeanFactory,解析 Spring 自身的 Bean,加入 BeanDefinitionMap
this();
// 【2】注册配置类,即 AppConfig 的 BeanDefinition,加入 BeanDefinitionMap
register(annotatedClasses);
refresh();
}
// 初始化 Spring 容器和 Bean
public void refresh() throws BeansException, IllegalStateException {
// 初始化当前的 Context 对象、BeanFactory,以及一些准备工作,扫描出 BeanDefinitionMap
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
// 【3】完成 Bean 的扫描,A/B 的 BeanDefinition,加入 BeanDefinitionMap
// 这里使用的是 ConfigurationClassPostProcessor(后置处理器)#processConfigBeanDefinitions
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor、国际化、事件分发等等方法
// 开始实例化单例的 Bean,不包含懒加载的
finishBeanFactoryInitialization(beanFactory);
} catch (BeansException ex) {
// 销毁已经创建的单例 Bean
destroyBeans();
}
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// ...
// 【4】实例化 Bean 流程的入口
beanFactory.preInstantiateSingletons();
}
复制代码
Spring Bean 实例化
实例化 Bean 的大致流程:
遍历所有扫描出来的 BeanDefinition,进行验证:是否 Lazy、是否 prototype、是否 abstract 等等
对 dependsOn 进行一些特殊处理,递归的实例化依赖的 bean
实例化 Bean
执行属性注入
执行 Bean 初始化
初始化完成,加入单例池
注册 DisposableBean(销毁 Bean 时回调方法)
在进入源码前,先看看几个概念
什么是 BeanDefinition
描述一个 Bean 实例(Instance)的各种属性,如:bean class、scope、lazyInit、dependsOn,isSingleton、isAbstract...,允许 bean factory 后置处理器,对 bean property 和其他元数据进行修改。实现类:
AbstractBeanDefinition
实现了大部分的方法,子类 AnnotatedBeanDefinition
可以获取注解信息。
什么是 MergedBeanDefinition
一个合并了 BeanDefinition 和 Parent BeanDefinition 的对象(递归处理),最终以 RootBeanDefinition
的类型存在。创建 Bean 的时候使用的都是 MergedBeanDefinition(mbd)
。在 Bean 的创建过程中,有多种后置处理器(例如: MergedBeanDefinitionPostProcessor
)进行扩展处理。
BeanFactory vs FactoryBean
BeanFactory 给具体的 IOC 容器的实现提供了规范,实现 BeanFactory 接口的类,表明此类是一个工厂,作用就是配置、新建、管理各种 Bean,例如:ApplicationContext
、 DefaultListableBeanFactory
、AbstractAutowireCapableBeanFactory
FactoryBean 是一种 Bean 类型,Spring 中有两种类型的 Bean,一种是普通 Bean,另一种是 FactoryBean,FactoryBean 提供 getObject()
方法返回 Bean,即通过将复杂的实例化 Bean 的逻辑封装到 FactoryBean 中由上层使用。
开始 Bean 的实例化
开始 Bean 的实例化,进入 beanFactory.preInstantiateSingletons();
方法查看(DefaultListableBeanFactory
)
public void preInstantiateSingletons() throws BeansException {
// 循环便利所有扫描出的 beanName
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 【1】过滤所有不符合条件的 beanDefinition,懒加载、非单例、抽象类
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (!isFactoryBean(beanName)) {
// 实例化 Bean 方法
getBean(beanName);
}
}
}
}
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
复制代码
getBean()
方法最终会进入 AbstractBeanFactory#doGetBean()
,实例化 Bean 的前置流程,通过流程图对照源码
代码解析
protected <T> T doGetBean(String name, Class<T> requiredType, Object[] args, boolean typeCheckOnly) {
/*
* 获取 name 对应的真正 beanName,传入的参数可以是 alias,也可能是 FactoryBean name,需要进行解析,包含以下内容:
* 1. 如果是 FactoryBean,则去掉修饰符 “&”
* 2. 沿着引用链获取 alias 对应的最终 name
*/
String beanName = this.transformedBeanName(name);
// 核心方法:从单例池中获取 bean,第一次 get 是 null,引申出两个问题:
// 1. 创建 bean 的时候,为什么要 get
// 2. bean 正在实例化,为什么要从缓存池中拿 bean
// 【推断】一个 bean 的实例化过程有可能进入超过一次
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
// 第一次不会进入这个分支
// 如果实例已经存在,返回实例
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
BeanFactory parentBeanFactory = this.getParentBeanFactory();
// 如果当前 bean 不在当前的 BeanFactory 中,从 Parent BeanFactory 中查找...
try {
// 将 GenericBeanDefinition 转换成 RootBeanDefinition(MergedBeanDefinition)
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
// 【2】进行一些验证,包括 dependsOn 的处理(控制 bean 的实例化顺序,递归的实例化依赖的 bean)
if (mbd.isSingleton()) {
// 如果 bean 是单例的,实例化 bean,这里是【核心方法】
sharedInstance = this.getSingleton(beanName, () -> {
try {
// 【3】实例化 Bean
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
// 失败的话,从缓存中移除,并执行 destory
this.destroySingleton(beanName);
throw var5;
}
});
// 返回实例
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else {
// Scope:Prototype... bean的处理逻辑
}
} catch (BeansException var26) {
throw var26;
}
}
// 类型检查和转换...
}
复制代码
Bean 缓存
Spring 中与 Bean 相关的缓存有三个
// 单例池,包含所有实例化完成的 Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 缓存 bean name -> ObjectFactory 的关系,ObjectFactory 创建对应的 bean
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 正在实例化的 bean,与单例池互斥
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
复制代码
第一个 getSingleton()
,表示缓存中获取 Bean 对象,Bean 第一次实例化会返回 null。
public Object getSingleton(String beanName) {
// 第二个参数表示允许早期依赖
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 先检查单例池
Object singletonObject = this.singletonObjects.get(beanName);
// 重点是第二个判断,如果 bean 正在创建中
// 在后面的方法中能看到,在 bean 第一次创建时,bean name 放入了 singletonsCurrentlyInCreation
// 当 bean 第二次调用方法时,进入 if 逻辑
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果 earlySingletonObjects 还没有 bean ,但是允许 allowEarlyReference
// 也就是提前暴露了 ObjectFactory,可通过 ObjectFactory 创建 bean 对象
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// bean 对象创建,并且加入 earlySingletonObjects,ObjectFactory 清除
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
return singletonObject;
}
复制代码
第二个 getSingleton()
,同样涉及几个重要的数据结构
// bean 第一次初始化开始阶段,加入 Set
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap(16));
// singletonFactory 就是 () => { this.createBean(...);}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Map var3 = this.singletonObjects;
synchronized(this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 第一次实例化,获取不到对象
// 加入 singletonsCurrentlyInCreation,表示 bean 开始(正在)实例化过程中
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
try {
// 通过 ObjectFactory 创建 bean,() => { this.createBean(...);}
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch(Exception e) {
// ...
} finally {
// 从 singletonsCurrentlyInCreation 移除,表示实例化完成
this.afterSingletonCreation(beanName);
}
if (newSingleton) {
// 【6】加入单例池 singletonObjects,移除其他缓存
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
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);
}
}
复制代码
一个无循环依赖的 Bean 的实例化过程中,缓存的使用(earlySingletonObjects
没有用到 )过程:
创建 Bean
回到 createBean()
方法(AbstractAutowireCapableBeanFactory
),此处时创建 bean 的真正逻辑,会有多处 Bean 扩展点调用
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) {
RootBeanDefinition mbdToUse = mbd;
// 解析 Bean Class
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 对 override 属性进行标记和验证
mbdToUse.prepareMethodOverrides();
Object beanInstance;
// 【后置处理器调用 1】InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
// 创建 Bean
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
// 实例化 Bean 的 Java 对象,属性还没有注入
if (instanceWrapper == null) {
// 【后置处理器调用 2】SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
synchronized(mbd.postProcessingLock) {
// 【后置处理器调用 3】MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
// 【重点关注】判断是否允许循环依赖
// 默认允许单例循环依赖 allowCircularReferences 属性值,修改这个属性可以改变 Spring 不允许循环依赖
boolean earlySingletonExposure = mbd.isSingleton()
&& this.allowCircularReferences
&& this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
// 当前 bean 正在实例化的过程中,将对应的 ObjectFactory 加入工厂集合 singletonFactories 中
// lambda 表示 ObjectFactory,返回 bean(mbd),添加了扩展点
// 提前暴露了 ObjectFactory 即当前未实例化完成的 bean
this.addSingletonFactory(beanName, () -> {
// 【后置处理器调用 4】SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference
// 【知识点】此处提前做了 AOP 代理
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
try {
// 【4】填充属性(注入)
this.populateBean(beanName, mbd, instanceWrapper);
// 【5】Bean初始化
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
// ...
}
// 再次基于依赖关系验证循环依赖的 bean 是否都已经实例化
// 【7】注册 DisposableBean,在销毁对应的 bean 时能够回调 destroy 方法
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
复制代码
addSingletonFactory()
方法,ObjectFactory 加入 singletonFactories,并且从 earlySingletonObjects 中移除
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
复制代码
Bean 后置处理器
后置处理器对所有的 Bean 都生效,需要自己实现筛选逻辑,上面遇到的几个后置处理器
InstantiationAwareBeanPostProcessor
postProcessBeforeInstantiation,bean 实例化前调用,是对 bean 定义进行修改【后置处理器调用 1】
postProcessAfterInstantiation,bean 实例化后调用,在属性注入之前【后置处理器调用 5】
postProcessProperties,在将属性注入 bean 实例前调用,对属性值修改【后置处理器调用 6】
MergedBeanDefinitionPostProcessor
postProcessMergedBeanDefinition,对 MergedBeanDefinition 进行处理,在属性注入之前【后置处理器调用 3】
Spring 自身实现 AutowiredAnnotationBeanPostProcessor
,解析 @Autowired
、@Value
、@Inject
用于后续的属性填充
SmartInstantiationAwareBeanPostProcessor
determineCandidateConstructors,解析 Bean 类里构造函数上的 @Autowired 注解,推断构造器,【后置处理器调用 2】
getEarlyBeanReference,AOP 代理【后置处理器调用 4】
实例化 Bean
通过工厂方法或构造函数创建,需要根据参数推断构造函数,否则使用默认构造函数
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 如果工厂方法不为空,则使用工厂方法进行实例化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 推断构造函数,利用构造函数进行实例化...
// 1. 使用特定构造函数注入
return autowireConstructor(beanName, mbd, null, null);
// 2. 默认构造函数
return instantiateBean(beanName, mbd);
}
复制代码
属性注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 【后置处理器调用 5】InstantiationAwareBeanPostProcessors#postProcessAfterInstantiation
if (!continueWithPropertyPopulation) {
// 如果后置处理器处理完,指明不需要执行后续的属性注入过程,则退出方法
return;
}
// 获取 bean 的属性值集合
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// autowire by name or autowire by type
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME
|| mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// autowire by name
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// autowire by type
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
// 【后置处理器调用 6】InstantiationAwareBeanPostProcessors#postProcessProperties
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// AutowiredAnnotationBeanPostProcessor 处理 @Autowired
// CommonAnnotationBeanPostProcessor 处理 @Resource
// ImportAwareBeanPostProcessor 处理 @Import
// 【此处会调用 CreateBean】
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
// 检查依赖
// 【执行属性注入】
applyPropertyValues(beanName, mbd, bw, pvs);
}
复制代码
循环依赖
回到开头的例子,在 Create A 时,在属性注入 A 的时候,会开始 Create B 的流程,在熟悉注入 B 的时候,又调用 Create A 的流程,逻辑就回到了刚才的 getSingleton()
方法。
// beanA 第二次进入
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 还没有单例实例
Object singletonObject = this.singletonObjects.get(beanName);
// A 正在创建
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// earlySingletonObjects 此时还没有(文章最后有流程图)
singletonObject = this.earlySingletonObjects.get(beanName);
// 允许提前暴露,此时 A -> ObjectFactory 存在
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
// 通过 ObjectFactory 获取 A
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// earlySingletonObjects 存入 A
this.earlySingletonObjects.put(beanName, singletonObject);
// 移除 ObjectFactory
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
复制代码
在回到调用 getSingleton()
方法的地方,返回 A 的 Bean 对象(目前还没有实例化完成),注入到 B 中
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 返回 Bean 实例(可能是未完成实例化的)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
复制代码
autowire
autowireByName 基于 beanName 获取依赖的 bean,并将依赖关系保存在对应的集合中,如果依赖的 bean 未被实例化则需要执行实例化逻辑:
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
// 依赖的 Bean 执行 getBean -> doGetBean
Object bean = getBean(propertyName);
// 添加到属性集合
pvs.add(propertyName, bean);
// 记录依赖关系
registerDependentBean(propertyName, beanName);
}
}
}
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
复制代码
autowireByType 相比于 autowireByName 多了一个类型推断过程,但是整体流程是相同的,依赖的 bean 未被实例化则需要执行实例化。
属性注入
将 bean 的所有属性全部注入到 bean 实例中,之前虽然已经创建了实例,但是属性仍然存在于 beanDefinition 实例中,applyPropertyValues 会将相应属性转换成 bean 中对应属性的真实类型注入到对应属性上:
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 属性类型转换的过程...
// 设置到 beanWrapper
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
复制代码
Bean 初始化
完成了属性注入,接下来容器会执行初始化方法,主要包含 4 个步骤:
调用所有 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 接口方法
BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 是 Spring 将数据暴露出去的一种方式,我们在自己的 bean 集成并实现对应的接口方法,会在此处被调用。
后置处理器 postProcessBeforeInitialization 调用,这里会执行 @PostConstruct 注解方法
执行初始化方法,InitializingBean 接口方法调用和 initMethod 方法调用
后置处理器 postProcessAfterInitialization 调用
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
// 调用所有 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 接口方法
invokeAwareMethods(beanName, bean);
// 【后置处理器调用 7】BeanPostProcessor#postProcessBeforeInitialization
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 执行初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
// 【后置处理器调用 8】BeanPostProcessor#postProcessAfterInitialization
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
复制代码
初始化方法
初始化方法的调用顺序,@PostConstruct 注解方法最先调用,然后调用 InitializingBean 接口方法,然后反射调用 init-method(如果 XML 中设置)。
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) {
// 如果 bean 继承了 InitializingBean 接口,优先调用 InitializingBean#afterPropertiesSet
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
((InitializingBean) bean).afterPropertiesSet();
}
// 如果设置了 initMethod 方法,并且这个类不是 InitializingBean 类型,并且方法名不是 afterPropertiesSet
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) {
String initMethodName = mbd.getInitMethodName();
final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
// 反射调用
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean);
}
复制代码
Bean 缓存的问题
刚刚提到与 Bean 相关的缓存有三个,通过 getSingleton()
方法逻辑可以看到其实是三级缓存
singletonObjects 是第一级缓存,存储实例化好的单例 Bean
singletonFactories 是第二级缓存,存储正在实例化的 Bean 的 ObjectFactory
earlySingletonObjects 是第三级缓存,存储正在实例化的 Bean
为什么要设计三级缓存?
假设改造 getSingleton()
为二级缓存,可以实现同样的功能
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
}
}
}
}
return singletonObject;
}
复制代码
为了防止重复创建,ObjectFactory 的代码会非常复杂,如果每次都通过工场创建性能浪费。并且 Bean 是单例的,对象创建出来之后可以在各处引用,不在需要 ObjectFactory。
同时解决了循环引用的 AOP 的问题,通过 ObjectFactory 提前做 AOP 代理,如果是直接返回对象,此时注入的对象还不是代理。
循环依赖
从源码可以看出来,Spring Bean 循环依赖的处理,主要是通过与 Bean 相关的三个缓存来实现的。
单向依赖
A->B,主要流程和缓存的变化
循环依赖
A->B,B->A,主要流程和缓存的变化
评论