目录
前置知识
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的beanName
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* 对registerSingleton方法的实现
*/
@Override
public 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
@Nullable
public Object getSingleton(String beanName) {
// 调用重载方法
return getSingleton(beanName, true);
}
/**
* getSingleton第二个参数是boolean类型的重载方法
*/
@Nullable
protected 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 {
@Autowired
private B b;
}
package spring.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* B依赖A
*/
@Component
public class B {
@Autowired
private 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对象的实例化和初始化逻辑,并将它们放入了容器的单例池中