Spring Bean 默认在单例的情况下支持循环依赖(属性注入)。如下代码启动执行不会异常:
@Configuration@ComponentScan("com.alex.space")public class AppConfig {
}
@Componentpublic class A { @Autowired B b;
public A() { System.out.println("constructor from A"); }}
@Componentpublic 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 Aconstructor from B========com.alex.space.A@247bddadcom.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 容器和 Beanpublic 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 相关的缓存有三个
// 单例池,包含所有实例化完成的 Beanprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 缓存 bean name -> ObjectFactory 的关系,ObjectFactory 创建对应的 beanprivate 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 第一次初始化开始阶段,加入 Setprivate 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,主要流程和缓存的变化
评论