目录
前置知识
SingletonBeanRegistry
DefaultSingletonBeanRegistry
Spring中处理循环引用的流程分析
定义两个具有循环引用特点的Bean
执行A的实例化
执行A的属性填充(执行过程中发现A依赖B,就去执行B的实例化逻辑)
执行B的实例化
执行B的属性填充
执行B的初始化
执行A的属性填充(此时依赖的B已经完成了实例化和初始化放到容器的单例池中,接着执行之前没有执行完成的A的属性填充逻辑)
执行A的初始化
前置知识
SingletonBeanRegistry
该接口中定义了一些和单例Bean有关的方法
package org.springframework.beans.factory.config;public interface SingletonBeanRegistry {/*** 往容器中添加单例bean对象*/void registerSingleton(String beanName, Object singletonObject);/*** 通过bean名字获取bean对象*/Object getSingleton(String beanName);/*** 判断容器中是否包含某bean名字的单例bean*/boolean containsSingleton(String beanName);/*** 获取容器中所有单例bean的名称集合*/String[] getSingletonNames();/*** 获取容器中单例bean对象的数量*/int getSingletonCount();
}
DefaultSingletonBeanRegistry
- 定义了三个Map集合(也就是常说的三级缓存)
- 定义了一个Set集合,用于存储正在创建的单例Bean的beanName
- 对SingletonBeanRegistry接口提供方法的实现
package org.springframework.beans.factory.support;public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {// 一级缓存private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);// 三级缓存private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);// 二级缓存private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);// ...// 正在创建的单例Bean的beanNameprivate final Set<String> singletonsCurrentlyInCreation =Collections.newSetFromMap(new ConcurrentHashMap<>(16));/*** 对registerSingleton方法的实现*/@Overridepublic void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {// ...synchronized (this.singletonObjects) {// 通过beanName先从一级缓存中获取Object oldObject = this.singletonObjects.get(beanName);// 一级缓存中已经有该beanName的对象,就抛异常if (oldObject != null) {throw new IllegalStateException("Could not register object [" + singletonObject +"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");}// 一级缓存中没有该beanName的对象,就执行添加逻辑addSingleton(beanName, singletonObject);}}/*** 往容器中添加Bean*/protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {// beanName作为key,bean对象作为value,往一级缓存中添加this.singletonObjects.put(beanName, singletonObject);// 删除三级缓存中key为beanName的节点this.singletonFactories.remove(beanName);// 删除二级缓存中key为beanName的节点this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}// .../*** 对getSingleton方法的实现(通过beanName获取bean对象)*/ @Override@Nullablepublic Object getSingleton(String beanName) {// 调用重载方法return getSingleton(beanName, true);}/*** getSingleton第二个参数是boolean类型的重载方法*/@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {// 先从一级缓存中获取bean对象Object singletonObject = this.singletonObjects.get(beanName);// 一级缓存中没有该beanName对应的对象并且该beanName正在被创建if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {// 从二级缓存中获取singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {// 从三级缓存中获取ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {// 执行三级缓存中的Lambda表达式的逻辑singletonObject = singletonFactory.getObject();// 放入二级缓存this.earlySingletonObjects.put(beanName, singletonObject);// 删除三级缓存中key为beanName的节点this.singletonFactories.remove(beanName);}}}}// 返回bean对象return singletonObject;}/*** getSingleton的重载方法* 第二个参数为Lambda表达式,为bean的创建过程*/public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {// ...synchronized (this.singletonObjects) {// 先从一级缓存中获取bean对象Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {// bean正在被创建,抛异常if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName,"Singleton bean creation not allowed while singletons of this factory are in destruction " +"(Do not request a bean from a BeanFactory in a destroy method implementation!)");}// ...// 创建bean之前,做一个标记,标记该beanName的bean正在创建中beforeSingletonCreation(beanName);boolean newSingleton = false;// ...try {// 执行Lambda的逻辑,执行bean的实例化和初始化流程singletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {// ...}catch (BeanCreationException ex) {// ...}finally {// ...// 移除该beanName正在创建对象的标识afterSingletonCreation(beanName);}if (newSingleton) {// 将完成实例化和初始化的bean对象放入单例池中addSingleton(beanName, singletonObject);}}// 返回bean对象return singletonObject;}}
}
Spring中处理循环引用的流程分析
定义两个具有循环引用特点的Bean
package spring.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** A依赖B*/
@Component
public class A {@Autowiredprivate B b;
}
package spring.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** B依赖A*/
@Component
public class B {@Autowiredprivate A a;
}
执行A的实例化
一、DefaultListableBeanFactory#preInstantiateSingletons
遍历beanNames,根据beanName实例化非懒加载的单例Bean
二、AbstractBeanFactory#getBean
getBean - doGetBean
三、AbstractBeanFactory#doGetBean
先尝试从容器中获取,有就直接返回
四、DefaultSingletonBeanRegistry#getSingleton
此时单例池singletonObjects中并没有beanName为a的对象,且并没有正在创建中,所以返回null
五、AbstractBeanFactory#doGetBean
调用getSingleton方法并传入beanName+Lambda表达式
六、DefaultSingletonBeanRegistry#getSingleton
- 此时singletonObjects中没有a
- 标记a正在创建中
- 执行传入的Lambda表达式,即createBean方法
七、AbstractAutowireCapableBeanFactory#createBean
createBean - doCreateBean
八、AbstractAutowireCapableBeanFactory#doCreateBean
- Bean的实例化
- 可以看到,Bean对象已经创建(A@2126)
- 添加到singletonFactories中(key为beanName,value为ObjectFactory)
九、AbstractAutowireCapableBeanFactory#getEarlyBeanReference
并非将已经实例化但未初始化的Bean对象直接放入singletonFactories(三级缓存)中,考虑到代理对象,所以放入的是Lambda表达式,也就是该方法的执行逻辑
十、DefaultSingletonBeanRegistry#addSingletonFactory
放入singletonFactories(三级缓存)中,key为beanName,value为一个Lambda表达式
执行A的属性填充(执行过程中发现A依赖B,就去执行B的实例化逻辑)
一、AbstractAutowireCapableBeanFactory#doCreateBean
填充Bean
二、AbstractAutowireCapableBeanFactory#populateBean
- @Autowired注解是通过AutowiredAnnotationBeanPostProcessor解析的
- 这里执行AutowiredAnnotationBeanPostProcessor的postProcessProperties方法
三、AutowiredAnnotationBeanPostProcessor#postProcessProperties
找到A中的b字段需要注入
四、InjectionMetadata#inject
调用AutowiredAnnotationBeanPostProcessor中的inject方法
五、AutowiredAnnotationBeanPostProcessor#inject
调用DefaultListableBeanFactory的resolveDependency方法
六、DefaultListableBeanFactory#resolveDependency
resolveDependency - doResolveDependency
七、DefaultListableBeanFactory#doResolveDependency
- autowiredBeanName:依赖的beanName
- instanceCandidate:依赖的bean类型
八、DependencyDescriptor#resolveCandidate
调用DefaultListableBeanFactory的getBean方法,此时beanName为b,也就是接下来要执行B的实例化、属性填充、初始化逻辑
执行B的实例化
一、AbstractBeanFactory#getBean
getBean - doGetBean
二、AbstractBeanFactory#doGetBean
此时容器中没有b对象,返回null
三、AbstractAutowireCapableBeanFactory#createBean
createBean - doCreateBean
四、AbstractAutowireCapableBeanFactory#doCreateBean
- Bean的实例化
- 实例化后的Bean对象和Bean的类型
- 将b和对应的Lambda表达式添加到三级缓存中
- 此时三级缓存中存在a,b两个元素
- 填充b对象属性
执行B的属性填充
一、AbstractAutowireCapableBeanFactory#populateBean
同样的,通过AutowiredAnnotationBeanPostProcessor的postProcessProperties方法中处理@Autowired注解
二、AutowiredAnnotationBeanPostProcessor#postProcessProperties
找到B依赖A
三、InjectionMetadata#inject
执行AutowiredAnnotationBeanPostProcessor的inject方法进行属性注入
四、AutowiredAnnotationBeanPostProcessor#inject
调用DefaultListableBeanFactory的resolveDependency方法
五、DefaultListableBeanFactory#resolveDependency
resolveDependency - doResolveDependency
六、DefaultListableBeanFactory#doResolveDependency
获取到注入的beanName和类型,调用DependencyDescriptor的resolveCandidate方法
七、DependencyDescriptor#resolveCandidate
从容器中获取a对象
八、AbstractBeanFactory#getBean
getBean - doGetBean
九、DefaultSingletonBeanRegistry#getSingleton
此时发生了改变
- 从singletonObjects(一级缓存)中获取a,没有
- beanName为a的Bean正在创建
- 从earlySingletonObjects(一级缓存)中获取a,同样没有
- 但是,从三级缓存singletonFactories中获取a,能获取到,此时执行三级缓存中a对应的Lambda表达式的逻辑
- 执行Lambda表达式后拿到a对象
- 将a对象(实例化了但未进行初始化)放入二级缓存中
- 删除三级缓存中的a
十、AutowiredAnnotationBeanPostProcessor#inject
通过反射将a对象赋值给b对象的a字段
执行B的初始化
一、AbstractAutowireCapableBeanFactory#doCreateBean
调用initializeBean执行b对象后续的初始化逻辑
二、AbstractAutowireCapableBeanFactory#initializeBean
- Aware接口方法的回调(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
- BeanPostProcessor的初始化前方法回调
- InitializingBean的afterPropertiesSet方法回调和自定义的初始化方法回调
- BeanPostProcessor的初始化后方法回调
- 返回完成初始化的b对象
三、DefaultSingletonBeanRegistry#getSingleton
- 此时已经执行完b对应的Lambda表达式的doCreateBean的逻辑,拿到的是b已经实例化并初始化好的Bean对象
- 删除b正在创建的标识
- 将b添加到一级缓存singletonObjects单例池中,删除三级缓存和二级缓存中的b
- 返回已经实例化并初始化好的b对象
执行A的属性填充(此时依赖的B已经完成了实例化和初始化放到容器的单例池中,接着执行之前没有执行完成的A的属性填充逻辑)
一、AutowireAnnotationBeanPostProcessor#inject
通过反射将b对象赋值给a对象的b字段(b对象中的a字段此时的值为完成了实例化但未进行初始化的a对象,没有进行初始化的对象并不影响别的对象去引用,后续对a对象进行初始化即可)
执行A的初始化
一、AbstractAutowireCapableBeanFactory#doCreateBean
执行a对象的初始化逻辑
二、DefaultSingletonBeanRegistry#getSingleton
执行完a对象的初始化逻辑,将a添加到一级缓存singletonObjects中,删除三级缓存和二级缓存中的a,至此完成了相互引用的a和b对象的实例化和初始化逻辑,并将它们放入了容器的单例池中