流程概览
singleton 作用域下的 Bean 整个创建过程要经历以下几个步骤
getBean(){
doGetBean(){
createBean(){
doCreateBean(){}
}
}
}
上面带层次的伪代码,只是帮助大家理解这几个重要方法对应的层次,其中 do 开头的才是真正干活的方法
在 singleton 作用域下, Bean 创建过程从 Ioc 容器的 getBean()方法开始,它会调用 doGetBean() 方法获取 Bean。
而真正干活的方法 doGetBean() 方法,首先会从缓存中获取,如果获取不到就调用 createBean() 方法
同理 createBean() 方法也会调用 doCreateBean() 来进行真正的创建工作,之后doCreateBean() 会对 Bean 进行实例化 -> 属性赋值 -> 初始化,最后将创建好的 Bean 放入缓存中
流程总结
在整个流程中,我们只需要关心 doGetBean() 、doCreateBean() 两个“真正干活”的方法,这两个方法做的事情也很简单
doGetBean(): 从缓存中获取 Bean,没有就调用创建方法doCreateBean(): 创建 Bean,并将其放入缓存中
虽然说的很简单,但其实这两个方法里面有大量精巧的设计,初次学习会有点难度,需要多学习几遍
三级缓存
上面提到 doGetBean() 方法首先会从缓存中获取 Bean,这个缓存就是常说的 Spring 三级缓存
它们其实就是三个 Map ,位于 DefaultSingletonBeanRegistry 类下
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
// 第一级缓存,缓存 初始化 完的 bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 第二级缓存,缓存 实例化 完的 bean
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 第三级缓存,缓存 bean Factory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 记录已创建过的 Bean
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
// 记录正在创建中的 Bean
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
}
各级缓存的作用:
- 第一级缓存
singletonObjects:缓存 初始化 完的 bean ,实现 Bean 的 singleton 作用域,即 Bean 的单例模式 - 第二级缓存
earlySingletonObjects:缓存 “bean 的提前引用(Bean 或 Bean 的代理对象)” ,解决循环依赖 - 第三级缓存
singletonFactories:缓存获取 “bean 的提前引用” 的工厂,推迟 Bean 或 Bean 的代理对象的获取时机
doGetBean() 方法
AbstractBeanFactory.doGetBean() 方法是真正获取 Bean 的核心方法,它里面做的事情非常多,这里只关注最最最重要的2处代码
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 1.根据 beanName 尝试从缓存中获取 Bean,如果缓存中有,则直接return,如果缓存中没有,且Bean不在创建中则返回null
Object beanInstance = getSingleton(beanName);
...
if (!typeCheckOnly) {
//标记名称为 {beanName} 的 Bean 正在创建中
markBeanAsCreated(beanName);
}
// 2.创建 Bean。 虽然方法名称也叫 getSingleton ,但是它传入了一个可以创建 Bean 的匿名函数,它会在内部调用该匿名函数,进行 Bean 的“创建”
sharedInstance = getSingleton(beanName, () -> { return createBean(beanName, mbd, args); });
}
}
极简版如下
doGetBean(){
//1. 获取 Bean
getSingleton(beanName);
//2. “创建” Bean
getSingleton(beanName, () -> { return createBean(beanName, mbd, args); });
}
这两个 getSingleton() 方法都位于 DefaultSingletonBeanRegistry 类下,一个一个来看
getSingleton(beanName)
首先来看 getSingleton(beanName); 方法,它其实是调用了 getSingleton(beanName, true); 方法
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从第一级缓存 singletonObjects 中取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 没取到,从第二级缓存 earlySingletonObjects 中取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 还没取到,从第三级缓存 singletonFactories 中取出该 bean 的工厂对象
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 通过工厂对象生产该 bean 的实例,注意这里拿到的可能是一个 bean 的代理对象
singletonObject = singletonFactory.getObject();
// 然后添加到第二级缓存 earlySingletonObjects 中
this.earlySingletonObjects.put(beanName, singletonObject);
// 最后删除掉第三级缓存 singletonFactories 中该 bean 的工厂
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
}
极简版如下
getSingleton() {
// 1 从第一级缓存 singletonObjects 中取
singletonObject = this.singletonObjects.get(beanName);
// 2 没取到,从第二级缓存 earlySingletonObjects 中取
singletonObject = this.earlySingletonObjects.get(beanName);
if (allowEarlyReference) {
// 3-1 还没取到,从第三级缓存 singletonFactories 中取出该 bean 的工厂对象
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
// 3-2 通过工厂对象生产该 bean 的实例,注意这里拿到的可能是一个 bean 的代理对象
singletonObject = singletonFactory.getObject();
// 3-3然后添加到第二级缓存 earlySingletonObjects 中
this.earlySingletonObjects.put(beanName, singletonObject);
// 3-4最后删除掉第三级缓存 singletonFactories 中该 bean 的工厂
this.singletonFactories.remove(beanName);
}
return singletonObject;
}
getSingleton(beanName, ObjectFactory<?>)
这就是上面 doGetBean() 中调用“创建” Bean 的方法
//2. “创建” Bean
getSingleton(beanName, () -> { return createBean(beanName, mbd, args); });
这个方法中做的事情也非常多,我们只看最最最重要的几块
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
// 创建前的处理
beforeSingletonCreation(beanName);
//1.创建 bean。singletonFactory 对象,就是上面那段的匿名函数,getObject()方法对应的就是匿名函数的具体实现
singletonObject = singletonFactory.getObject();
// 创建后的处理
afterSingletonCreation(beanName);
// 2.将 bean 添加到缓存中
addSingleton(beanName, singletonObject);
return singletonObject;
}
极简版如下
getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
//1.创建 bean。相当于 singletonObject = createBean(beanName, mbd, args);
singletonObject = singletonFactory.getObject();
// 2.将 bean 添加到缓存中
addSingleton(beanName, singletonObject);
}
这里面又有两个重要的方法
-
createBean(beanName, mbd, args): 这个就是文章开头提到的createBean()方法 -
addSingleton(beanName, singletonObject): 添加 Bean 到第一级缓存中
我们先看 addSingleton(beanName, singletonObject) 方法
addSingleton()
这个方法同样位于 DefaultSingletonBeanRegistry 类下,而且源码非常简单,如下
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 将 Bean 添加到第一级缓存中
this.singletonObjects.put(beanName, singletonObject);
// 将 Bean 从第三级缓存中删除
this.singletonFactories.remove(beanName);
// 将 Bean 从第二级缓存中删除
this.earlySingletonObjects.remove(beanName);
// 标记 {beanName} 对应的 Bean 已创建
this.registeredSingletons.add(beanName);
}
}
this.registeredSingletons 是 DefaultSingletonBeanRegistry 类的一个属性
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
代表着已创建过的 Bean
doGetBean() 方法总结
以下极简版的 doGetBean() 整个流程,最重要的是在第二次 getSingleton() 时,传入了一个 ObjectFactory的实现类,实现了 创建 Bean 的方法,之后在方法内部会调用该方法,进入到创建 bean 的阶段
doGetBean(){
getSingleton(beanName);
getSingleton(beanName, () -> { return createBean(beanName, mbd, args); });
}
getSingleton(beanName){
// 1 从第一级缓存 singletonObjects 中取
singletonObject = this.singletonObjects.get(beanName);
// 2 没取到,从第二级缓存 earlySingletonObjects 中取
singletonObject = this.earlySingletonObjects.get(beanName);
if (allowEarlyReference) {
// 3-1 还没取到,从第三级缓存 singletonFactories 中取出该 bean 的工厂对象
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
// 3-2 通过工厂对象生产该 bean 的实例
singletonObject = singletonFactory.getObject();
// 3-3然后添加到第二级缓存 earlySingletonObjects 中
this.earlySingletonObjects.put(beanName, singletonObject);
// 3-4最后删除掉第三级缓存 singletonFactories 中该 bean 的工厂
this.singletonFactories.remove(beanName);
}
}
getSingleton(beanName, beanFactory){
// 1.创建 bean。相当于 singletonObject = createBean(beanName, mbd, args);
singletonObject = singletonFactory.getObject();
// 2.将 bean 添加到缓存中
addSingleton(beanName, singletonObject);
}
addSingleton(beanName, singletonObject){
// 将 Bean 添加到第一级缓存中
this.singletonObjects.put(beanName, singletonObject);
// 将 Bean 从第三级缓存中删除
this.singletonFactories.remove(beanName);
// 将 Bean 从第二级缓存中删除
this.earlySingletonObjects.remove(beanName);
// 标记 {beanName} 对应的 Bean 已创建
this.registeredSingletons.add(beanName);
}
createBean(beanName, mbd, args)
上面说到,doGetBean() 获取不到对象,会来调用 createBean(beanName, mbd, args),我们来看下 createBean() 方法中做了什么事情,如下只保留了最最最核心的代码
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
// 拿到 Bean 的 Definition 对象
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 调用 doCreateBean() 方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
}
}
这里面最重要的还是 doCreateBean() 方法,我们直接看该方法
doCreateBean() 方法
doCreateBean() 方法位于 AbstractAutowireCapableBeanFactory 类下,这个方法的内容也非常多,我们只看最最最重要的
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
// 1.实例化 Bean,并从返回的 BeanWrapper 包装类中取出 bean 对象。注意此时 bean 还是原始对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
final Object bean = instanceWrapper.getWrappedInstance();
// 是否”提前暴露“原始对象的引用,用于解决循环依赖。对于单例Bean,该变量一般为 true
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
//2.往第三级缓存中添加一个 ObjectFactory 接口的实现类,就是下面这个匿名函数,调用该匿名函数可以获得一个 bean 对象或者 bean 的代理对象,实现 AOP
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 3.填充属性(依赖注入)
populateBean(beanName, mbd, instanceWrapper);
// 4. Bean初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
极简版
doCreateBean(){
// 1.实例化 Bean
createBeanInstance(beanName, mbd, args);
//2.往第三级缓存中添加一个 ObjectFactory 接口的实现类,就是下面这个匿名函数,调用该匿名函数可以获得一个 bean 对象或者 bean 的代理对象
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 3.填充属性(依赖注入)
populateBean(beanName, mbd, instanceWrapper);
// 4. Bean初始化
initializeBean(beanName, exposedObject, mbd);
}
这上面的每一个方法都非常重要,我们先看 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 这句代码
getEarlyBeanReference()
这个方法很有意思,名称叫做 获取 bean 的提前引用,什么叫“提前引用” 这是为了解决循环依赖提出来的,可以理解为一个已经实例化但还没有填充属性的对象
关于循环依赖这块,参考 Spring 循环依赖
getEarlyBeanReference() 方法源码如下
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
虽说方法名称叫做获取 bean 的提前引用,但是你看入参,已经传入了一个 bean 对象,结合 doCreateBean() 方法中的代码
//实例化 Bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
final Object bean = instanceWrapper.getWrappedInstance();
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
这里传进去的 bean 就是一个 "提前引用"(已经实例化但还没有填充属性的对象)
你可能有疑问了,既然已经有了 "提前引用" 那还有必要调用 getEarlyBeanReference(beanName, mbd, bean) 再次获取 bean 的提前引用吗?
其实 getEarlyBeanReference(beanName, mbd, bean) 方法真正的作用是,如果传入的 bean 被代理,则返回代理对象,否则原样返回,核心代码就下面一句
// AbstractAutoProxyCreator 会继承 SmartInstantiationAwareBeanPostProcessor 并重写 getEarlyBeanReference 方法,返回一个代理对象
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
ibp 是 SmartInstantiationAwareBeanPostProcessor 类型,getEarlyBeanReference(exposedObject, beanName) 方法用于返回一个 "提前引用" ,默认实现是将 bean 原样返回,但如果我们使用 Spring AOP 对该 Bean 进行了代理,那么 ibp 可能对应SmartInstantiationAwareBeanPostProcessor 的子类,比如 AbstractAutoProxyCreator ,它继承了 SmartInstantiationAwareBeanPostProcessor 并重写了 getEarlyBeanReference(); 方法,返回了一个代理对象
addSingletonFactory()
addSingletonFactory() 同样位于 DefaultSingletonBeanRegistry 类下,方法也很简单,源码如下:
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 如果 bean 不在第一级缓存中
if (!this.singletonObjects.containsKey(beanName)) {
// 将 ObjectFactory 接口的实现类,就是上一节中的匿名函数添加到第三级缓存中
this.singletonFactories.put(beanName, singletonFactory);
// 将 bean 从删除第二级缓存中删除
this.earlySingletonObjects.remove(beanName);
// 将该 bean 标记为已注册
this.registeredSingletons.add(beanName);
}
}
}
有了上面的了解,我们再回头来看 doGet() 中的这段代码
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
将一个匿名函数添加到了第三级缓存中,而这个匿名函数可能会获得一个 bean 的代理对象
还记得这个第三级缓存什么时候被用到吗?在 doGetBean() 的时候,我们用来了 getSingleton(beanName); 方法,它里面会去使用第三级缓存,让我们重新回顾一下 getSingleton() 方法
getSingleton() {
// 1 从第一级缓存 singletonObjects 中取
singletonObject = this.singletonObjects.get(beanName);
// 2 没取到,从第二级缓存 earlySingletonObjects 中取
singletonObject = this.earlySingletonObjects.get(beanName);
if (allowEarlyReference) {
// 3-1 还没取到,从第三级缓存 singletonFactories 中取出该 bean 的工厂对象
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
// 3-2 通过工厂对象生产该 bean 的实例
singletonObject = singletonFactory.getObject();
// 3-3然后添加到第二级缓存 earlySingletonObjects 中
this.earlySingletonObjects.put(beanName, singletonObject);
// 3-4最后删除掉第三级缓存 singletonFactories 中该 bean 的工厂
this.singletonFactories.remove(beanName);
}
return singletonObject;
}
上面 3-1 中 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); 得到的 singletonFactory 就是上面 doCreateBean() 中设置进去的匿名函数
3-2 中 singletonFactory 调用 getObject(); 方法,就是执行匿名函数中的 getEarlyBeanReference(beanName, mbd, bean) 方法,所以,3-2 中返回的 singletonObject 对象,可能是一个代理对象
3-3 中把 singletonObject 对象(可能是一个代理对象),放入了二级缓存,之后在 3-4 中,移除了匿名函数
addSingletonFactory() 的设计思想
回头来看这段代码
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
为什么不这样写
// 获取到 bean 的“提前引用”,这个 “提前引用” 可能是一个代理对象
Object EarlyBean = getEarlyBeanReference(beanName, mbd, bean);
// 跳过第三级缓存,直接添加到第二级缓存中
addEarlySingleton(beanName, EarlyBean);
我是这样理解的,addSingletonFactory() 这样设计的目的是推迟 bean "提前引用" 的获取时机,只有 getSingleton() 时,才会真正获取 bean 的"提前引用"
populateBean()
doCreateBean() 中的 populateBean() 方法同样位于 AbstractAutowireCapableBeanFactory 类下,用于给实例化完的 bean 填充属性(注入依赖),我们只看最最最重要的三块代码
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 1.基于 byName 的自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 2.基于 byType 的自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 3.填充属性
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
上面的1、2、3 三种方式都可以给 bean 填充属性,具体使用哪一中方法给 bean 填充属性,要看 mbd.getResolvedAutowireMode() 的返回结果
getResolvedAutowireMode() 源码如下
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable {
// 不自动装配
public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
// 根据 bean 的名称进行自动装配
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
// 根据 bean 的类型进行自动装配
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
// 根据构造方法进行自动装配
public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
// 自动检测
@Deprecated
public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
// 默认不自动装配
private int autowireMode = AUTOWIRE_NO;
public int getResolvedAutowireMode() {
if (this.autowireMode == AUTOWIRE_AUTODETECT) {
Constructor<?>[] constructors = getBeanClass().getConstructors();
for (Constructor<?> constructor : constructors) {
if (constructor.getParameterCount() == 0) {
return AUTOWIRE_BY_TYPE;
}
}
return AUTOWIRE_CONSTRUCTOR;
}
else {
return this.autowireMode;
}
}
}
如果没有显式配置自动装配策略,例如如在 XML 配置文件中显式指定了 autowired 或者在 Java 配置类中 @Bean 上,声明 autowired
<bean id="a" class="com.wqlm.Test.A" autowire="byName">
<property name="b" value="1" />
</bean>
@Bean(autowire = Autowire.BY_NAME)
那么autowireMode 为默认值, autowireMode = AUTOWIRE_NO ,不走 1、2 分支的,而是执行3 中的代码,我们平常使用@Resource 、@Autowired 注解来进行字段或者 setter() 注入都是执行3 中的代码
我们仔细来分析一下3 中的代码
// 拿到当前所有实现了 BeanPostProcessor 接口的实现类,并遍历
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// InstantiationAwareBeanPostProcessor 是 BeanPostProcessor 的子接口
if (bp instanceof InstantiationAwareBeanPostProcessor) {
// 类型转换
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 3.填充属性
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
其实就是调用所有 InstantiationAwareBeanPostProcessor 接口的实现类的 postProcessPropertyValues()方法
该接口的实现类特别多,这里只需要关注AutowiredAnnotationBeanPostProcessor,从名字中就可以看出,它是对基于注解(@Resource 、@Autowired)的自动装配进行 BeanPostProcessor
当我们使用注解(@Resource 、@Autowired)的方式进行依赖注入时,在 populateBean() 中会调用 AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues() 方法
而从堆栈中我们可以看到,它最终会去调用 doGetBean() 去获取/创建依赖 bean,之后通过反射或 setter() 方法,将获取到的 bean 填充到属性中
这就是属性填充的基本流程,用伪代码表示就是
populateBean(){
AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(){}
}
postProcessPropertyValues(){
// 获取依赖对象
Object o = doGetBean();
// 设置依赖
bean.setxxx(o);
}
initializeBean()
populateBean() 方法执行完成之后,Bean 中的依赖就都填充好了,而 initializeBean() 方法是进一步对 Bean 进行扩展和增强,如果我们的 Bean 实现了以下这些接口,那么会按照顺序依次调用对应的方法
doCreateBean() 方法总结
以下极简版的 doCreateBean() 整个流程
doCreateBean(){
// 1.实例化 Bean
createBeanInstance(beanName, mbd, args);
//2.往第三级缓存中添加一个 ObjectFactory 接口的实现类,就是下面这个匿名函数,调用该匿名函数可以获得一个 bean 对象或者 bean 的代理对象
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 3.填充属性(依赖注入)
populateBean(beanName, mbd, instanceWrapper);
// 4. Bean初始化
initializeBean(beanName, exposedObject, mbd);
}
//2
addSingletonFactory(beanName, singletonFactory) {
// 如果 bean 不在第一级缓存中
if (!this.singletonObjects.containsKey(beanName)) {
// 将 ObjectFactory 接口的实现类,就是上面的匿名函数添加到第三级缓存中
this.singletonFactories.put(beanName, singletonFactory);
// 将 bean 从删除第二级缓存中删除
this.earlySingletonObjects.remove(beanName);
// 将该 bean 标记为已注册
this.registeredSingletons.add(beanName);
}
}
// 3 伪代码
populateBean(beanName, mbd, instanceWrapper){
// 获取依赖对象
Object o = doGetBean();
// 设置依赖
bean.setxxx(o);
}
上面最重要的是实例化后,调用 addSingletonFactory() 方法在第三级缓存中放入了一个可以拿到 bean 代理对象的 ObjectFactory 。以及填充属性时,通过 doGetBean() 在缓存中获取依赖
总结
整个生命周期用代码表示如下
doGetBean(){
//1. 从第一二三级缓存中依次获取 Bean
getSingleton(beanName);
//2. 获取不到,调用 createBean() 方法“创建” Bean
getSingleton(beanName, () -> { return createBean(beanName, mbd, args); });
}
doCreateBean(){
// 1.实例化 Bean
createBeanInstance(beanName, mbd, args);
//2.往第三级缓存中添加一个 ObjectFactory 接口的实现类,就是下面这个匿名函数,调用该匿名函数可以获得一个 bean 对象或者 bean 的代理对象
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 3.填充属性(依赖注入),调用上面 doGetBean()方法获取依赖bean 并填充到属性
populateBean(beanName, mbd, instanceWrapper);
// 4. Bean初始化
initializeBean(beanName, exposedObject, mbd);
}
上面的伪代码,就是 singleton Bean 的生命周期中,最最最核心的流程,它解释了 Bean AOP 的时机,三级缓存的作用,以及 Spring 如何解决循环依赖
Spring 如何解决循环依赖
让我们用一个循环依赖的例子来巩固整个流程