Spring-Bean初始化


​ 整体分析了BeanFactory和ApplicationContext的区别。并从Spring Bean创建流程源码分析了bean的创建流程并对其进行总结,并分析了三级缓存的作用

BeanFactory

BeanFactory 是 Spring 最基础的 IoC 容器接口,仅提供了 Bean 的获取与管理能力。而 DefaultListableBeanFactory 是其默认实现类,它通过实现多个关键接口,构建出完整的 IoC 容器功能体系。

以下是 DefaultListableBeanFactory 实现的主要接口以及其对应的职责:

主要接口 主要功能
AliasRegistry 提供 Bean 的别名注册和解析能力。允许一个 Bean 在容器中有多个名字,是 Spring IoC 容器灵活命名机制的基础。
BeanDefinitionRegistry 管理 Bean 的定义信息(BeanDefinition),提供注册、删除、查询等能力。是容器启动期间加载和维护元数据的关键接口。
SingletonBeanRegistry 管理单例 Bean 的注册与缓存机制,控制 Bean 的生命周期。所有单例 Bean 都存储在 singletonObjects 缓存中。
AutowireCapableBeanFactory 提供创建 Bean 实例、属性注入、初始化回调、AOP 代理等高级功能。
通常用于手动创建并管理 Bean 的生命周期,比如调用 createBean()autowireBean() 等。
ConfigurableListableBeanFactory BeanFactory 的高级配置接口,支持访问所有已注册的 BeanDefinition,还可以注册 BeanPostProcessor组件。
常用于容器初始化后对 BeanFactory 进行增强或定制
HierarchicalBeanFactory 支持父子容器结构,允许子容器从父容器中查找 Bean,提升模块化和隔离能力。
是实现 ApplicationContext 之间嵌套结构的基础。
FactoryBeanRegistrySupport (继承自 AbstractAutowireCapableBeanFactory 支持 FactoryBean 机制的关键实现类,负责识别并缓存 FactoryBean 创建的产品对象。
比如,当你定义了一个实现 FactoryBean<T> 的类时,容器最终会获取到 T 类型的对象,而不是工厂本身。

ApplicationContext

ApplicationContext不仅实现了BeanFactory接口,还多了许多拓展接口,其余接口如下

其他接口 主要功能
EnvironmentCapable 获取Environment,可读取各种配置
MessageSource 国际化消息解析
ApplicationEventPublisher 支持事件发布/监听机制
ResourcePatternResolver 支持资源加载,比如 classpath 等路径资源

​ 在注解驱动的环境下,常用的 ApplicationContext 实现类为 AnnotationConfigApplicationContext。该类内部封装了一个 DefaultListableBeanFactory 实例,作为底层的 Bean 注册与管理中心,从而继承了 BeanFactory 的全部能力。

​ 而其refresh方法更是容器启动流程的核心。Bean的解析、注册,各种后置处理器的准备、使用,国际化和事件发布、各种监听器均在这个方法中完成,可以说是整个Spring的核心

bean创建流程源码(只保留了重要的部分)

AbstractBeanFactory#doGetBean

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean方法部分关键代码

// 获取真实的beanName,参数name可能是bean的别名和FactoryBean格式(前面有&)
String beanName = transformedBeanName(name);
Object bean;

// Eagerly check singleton cache for manually registered singletons.
// 为了解决循环引用,在这里就必须可以从二级或三级缓存中拿bean(尽管此时这个bean实例化了,还未填充数据和初始化)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
  bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

else {
  // 循环创建多例bean抛出异常
  if (isPrototypeCurrentlyInCreation(beanName)) {
    throw new BeanCurrentlyInCreationException(beanName);
  }

  // 先获取父容器
  BeanFactory parentBeanFactory = getParentBeanFactory();
  // 父BeanFactory存在且当前的BeanFactory不存在BeanDefinition,就会去父BeanFactory递归查找
  if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    // 在父容器中获取bean,能获取到就直接返回了
    ...
  }

  if (!typeCheckOnly) {
    // 标记bean为已创建
    markBeanAsCreated(beanName);
  }

  try {
    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    checkMergedBeanDefinition(mbd, beanName, args);

    String[] dependsOn = mbd.getDependsOn();
    if (dependsOn != null) {
      // 有dependsOn的bean,则优先创建这些bean
      ...
    }

    // Create bean instance.
    if (mbd.isSingleton()) { // 单例bean的创建
      sharedInstance = getSingleton(beanName, () -> {
        try {
          return createBean(beanName, mbd, args);
        }
        catch (BeansException ex) {
                    // bean创建失败,执行destory相关方法并直接抛出异常
          destroySingleton(beanName);
          throw ex;
        }
      });
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    else if (mbd.isPrototype()) { // 创建多例bean
      Object prototypeInstance = null;
      try {
        beforePrototypeCreation(beanName);
        prototypeInstance = createBean(beanName, mbd, args);
      }
      finally {
        afterPrototypeCreation(beanName);
      }
      bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    }

    else { // 特殊的scope里bean的创建。创建在session,request等scope里面的bean
      String scopeName = mbd.getScope();
      Scope scope = this.scopes.get(scopeName);
      }
      // 获取并放入对应的Scope中,在返回bean
      Object scopedInstance = scope.get(beanName, () -> {
        beforePrototypeCreation(beanName);
        try {
          return createBean(beanName, mbd, args);
        }
        finally {
          afterPrototypeCreation(beanName);
        }
      });
      bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    }
  }
  catch (BeansException ex) {
    cleanupAfterBeanCreationFailure(beanName);
    throw ex;
  }
}

// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
    T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
    if (convertedBean == null) {
      throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    }
    return convertedBean;
}
return (T) bean;

DefaultSingletonBeanRegistry#getSingleton

从三级缓存中获取bean

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 先从一级缓存中直接获取
        Object singletonObject = this.singletonObjects.get(beanName);
        // 单例bean还没创建好但是正在创建的情况(说明已经有循环引用了)
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            // 二级缓存中获取
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                synchronized (this.singletonObjects) {
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) { // 一级缓存为空,从二级中取
                        singletonObject = this.earlySingletonObjects.get(beanName);
                        if (singletonObject == null) { // 二级缓存为空,再从三级缓存中获取
                            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                            if (singletonFactory != null) {
                                // 三级缓存不为空,取出该bean,放入二级缓存,同时从三级缓存中删除
                                singletonObject = singletonFactory.getObject();
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }
        return singletonObject;
    }

AbstractAutowireCapableBeanFactory#doCreateBean

// 实例化bean。先创建出一个空壳的bean,各种field和方法都没有填充和调用
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
  instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
  instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 已实例化的bean
Object bean = instanceWrapper.getWrappedInstance();
// bean 的class type
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
  mbd.resolvedTargetType = beanType;
}

// 单例+允许循环引用+当前bean正在创建。就需要将bean包装后放入三级缓存中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
  // 将已实例化但还未填充属性的bean放入三级缓存,供其他依赖此bean的bean使用
  addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

//  准备初始化bean
Object exposedObject = bean;
try {
  // 填充bean的字段(依赖的字段bean)
  populateBean(beanName, mbd, instanceWrapper);
  // bean完全填充好属性后,开始调用各种初始化方法和BeanPostProcessor接口
  exposedObject = initializeBean(beanName, exposedObject, mbd);
}
    ... // 省略异常
}
... 
// 注册destroy相关方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;

AbstractAutowireCapableBeanFactory#populateBean

填充bean的字段


PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

// 根据autowireMode来判断注入方式
// 1. xml显示配置的autowire
// 2. 配置了@Bean注解的autowire字段(这个字段默认不会走下面的代码注入)
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
  // Add property values based on autowire by name if applicable.
  if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    autowireByName(beanName, mbd, bw, newPvs);
  }
  // Add property values based on autowire by type if applicable.
  if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    autowireByType(beanName, mbd, bw, newPvs);
  }
  pvs = newPvs;
}
// ==================== 以下就是@Autowired和@Resource注入方式的处理
// 是否存在InstantiationAwareBeanPostProcessor处理器(主要是注解解析PostProcessor)
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
  if (pvs == null) {
    pvs = mbd.getPropertyValues();
  }
  // 获取InstantiationAwareBeanPostProcessor处理器,并调用其postProcessProperties方法
  // 基于注解的依赖注入会用到
  for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
      InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
      // 注解相关的自动注入
      PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
      pvs = pvsToUse;
    }
  }
}
}

AbstractAutowireCapableBeanFactory#initializeBean

初始化bean


// 三种aware(BeanName,BeanClassLoader,BeanFactory)
invokeAwareMethods(beanName, bean);

// 名叫wrappedBean,表示这些方法返回的bean可能是被包装后的,比如aop相关
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
  // BeanPostProcessor接口实例回调(在bean的初始化方法调用之前调用)
  // 例如:@PostConstruct注解的实现
  wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

// InitializingBean方法和init-method方法
invokeInitMethods(beanName, wrappedBean, mbd);

if (mbd == null || !mbd.isSynthetic()) {
  // BeanPostProcessor#postProcessAfterInitialization接口实例回调。
  // 在bean的初始化方法调用完成之后调用,说明bean以及初始化完毕,可以实现其他扩展功能了
  //比如AOP的实现、 @Scheduled注解实现等
  wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;

三级缓存相关

  • 一级缓存(DefaultSingletonBeanRegistry#singletonObjects):存放的是完全初始化好的bean,包括已实例化、填充内部依赖的bean,运行完初始化方法(@PostConstruct、afterPropertiesSet方法、指定的init-method方法)
  • 二级缓存(DefaultSingletonBeanRegistry#earlySingletonObjects):存放bean缓存(如果能被AOP,就是AOP对象),但还未填充属性和允许初始化方法
  • 三级缓存(DefaultSingletonBeanRegistry#singletonFactories):存放bean的ObjectFactory工厂对象,使用这个工厂对象,可提前暴露出bean的引用(专用来提前暴露AOP对象的方法)

循环依赖的解决方案

​ 首先,Spring 不希望出现 Bean 的循环依赖,但为了应对这种情况,Spring 还是提供了解决办法。

​ 具体做法是(仅在支持循环依赖的配置下生效):在填充字段和初始化之前,Spring 会把每个 Bean 包装成一个 ObjectFactory 对象,并放入三级缓存DefaultSingletonBeanRegistry#singletonFactories

​ 当发生循环依赖时,Spring 会触发三级缓存中的 ObjectFactory#getObject 获取该 Bean 的代理对象,并将代理对象放入二级缓存(DefaultSingletonBeanRegistry#earlySingletonObjects)中,这样一来,当其他依赖这个 Bean 的对象需要时,Spring 可以从二级缓存中取到代理后的 Bean,这样就能确保 无论是否 AOP,都能成功填充依赖关系

为什么要三级缓存

​ 三级缓存的核心作用是解决 AOP 对象的暴露问题,特别是在 循环依赖 的场景下

​ 如果没有 AOP,Spring 只需要使用 一级缓存二级缓存 就能解决循环依赖问题。因为没有代理对象,Bean 本身就是可以直接使用的

​ 但Spring是支持AOP的,其设计初衷是希望通过 后置处理器AnnotationAwareAspectJAutoProxyCreator)来完成 AOP 代理,而不是在 Bean 实例化时立即完成代理。如果没有三级缓存,Spring 就必须在bean实例化后立刻进行代理,将最终的代理bean放入二级缓存用于解决循环依赖 ,这个包装bean的过程提前了,和 Spring 原本的设计理念就冲突了

​ 所以出现了三级缓存,其仅在 循环依赖 的场景下提前暴露 AOP 代理对象没有循环依赖的情况下,依然使用后置处理器来完成 AOP 代理,走正常流程

依赖注入中未完全初始化对象的问题

如果有3个bean分别为A、B、C,A依赖B和C,B只依赖A,C什么都不依赖,但提供一个方法sayHello使用。

​ 当开始实例化A时,实例化A后将其工厂对象放入三级缓存中,开始填充A属性,发现了B需要填充,开始实例化B,实例化B对象过程中又需要填充其属性A,这时能从三级缓存中取出了A的引用(但此时A不完整),如果B对象有一个初始化方法(@PostConstruct),调用A对象里的C对象的sayHello方法,但由于A此时只是个空壳,就会抛出空指针异常。

​ 总的来说,就是在循环引用依赖主任期间的调用初始化方法时,使用了尚未完全创建好的bean内部某个未注入字段的某个方法,导致抛出NPE,导致服务启动失败

Bean创建流程总结

  1. 实例化 Bean:创建一个空壳 Bean(即没有依赖注入和初始化的 Bean 对象)
  2. 放入三级缓存:将 Bean 的工厂对象(ObjectFactory)放入三级缓存,以便后续处理循环依赖。(是否允许循环依赖取决于 AbstractAutowireCapableBeanFactory#allowCircularReferences 字段)
  3. 填充依赖AbstractAutowireCapableBeanFactory#populateBean):处理 Bean 的依赖注入(如 @Autowired@Resource)。Spring 会从 一级缓存、二级缓存、三级缓存 中查找依赖的 Bean。如果某个依赖 Bean 还未创建,会触发递归创建
  4. 初始化 BeanAbstractAutowireCapableBeanFactory#initializeBean
    1. 调用 BeanPostProcessor#postProcessBeforeInitialization 方法(初始化前的 Hook)
    2. 执行初始化方法:如 @PostConstructafterPropertiesSet()init-method 方法等
    3. 调用 BeanPostProcessor#postProcessAfterInitialization 方法(初始化后的 Hook,涉及 AOP 等)
  5. 注册销毁方法AbstractBeanFactory#registerDisposableBeanIfNecessary):注册销毁方法,以便在容器关闭时执行
  6. 创建完成:将 Bean 放入一级缓存,同时从二级缓存和 三级缓存中移除该 Bean 对应的对象