Spring 源码:IOC-循环依赖

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 容器创建后初始化的的大概描述,包括容器的创建:

  1. 实例化 ApplicationContext
  2. 注册配置类,解析配置类的 BeanDefinition 加入 BeanDefinitionMap
  3. 完成 Bean 的扫描,解析所有 BeanDefinition,加入 BeanDefinitionMap
  4. 实例化 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 的大致流程:

  1. 遍历所有扫描出来的 BeanDefinition,进行验证:是否 Lazy、是否 prototype、是否 abstract 等等
  2. 对 dependsOn 进行一些特殊处理,递归的实例化依赖的 bean
  3. 实例化 Bean
  4. 执行属性注入
  5. 执行 Bean 初始化
  6. 初始化完成,加入单例池
  7. 注册 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,例如:ApplicationContextDefaultListableBeanFactoryAbstractAutowireCapableBeanFactory

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 个步骤:

  1. 调用所有 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 接口方法
    1. BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 是 Spring 将数据暴露出去的一种方式,我们在自己的 bean 集成并实现对应的接口方法,会在此处被调用。
  2. 后置处理器 postProcessBeforeInitialization 调用,这里会执行 @PostConstruct 注解方法
  3. 执行初始化方法,InitializingBean 接口方法调用和 initMethod 方法调用
  4. 后置处理器 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,主要流程和缓存的变化


Add a Comment

电子邮件地址不会被公开。 必填项已用*标注