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对象的方法)

为什么要使用三级缓存

三级缓存专门来解决AOP对象的暴露问题

​ 如果没用AOP是可以只用一级缓存和二级缓存就解决的。但如果使用了AOP且没有三级缓存,那么必须在实例化后就马上完成AOP代理,但这和spring的设计初衷不同,AOP代理的完成时使用了bean的后置处理器AnnotationAwareAspectJAutoProxyCreator来完成的,也就是在初始化bean后执行的bean后置处理器方法(AbstractAutowireCapableBeanFactory#initializeBean),就不可能再实例化bean后进行代理,所以才有了三级缓存,仅用来提前暴露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(空壳bean)的某个字段的方法,导致抛出NPE,导致服务启动失败

关键流程总结

  1. 实例化bean:创建bean的空壳对象
  2. 将其工厂对象(ObjectFactory)放入三级缓存(根据AbstractAutowireCapableBeanFactory#allowCircularReferences字段决定)
  3. 填充依赖bean(AbstractAutowireCapableBeanFactory#populateBean):进行@Autowired和@Resource等注解的字段注入。如果这些依赖的 Bean 还没创建,会触发递归创建
  4. 初始化bean(AbstractAutowireCapableBeanFactory#initializeBean
    • 4.1 调用BeanPostProcessor#postProcessBeforeInitialization方法(初始化前的hook)
    • 4.2 调用各种初始化方法(**@PostConstruct、afterPropertiesSet方法、指定的init-method方法**)
    • 4.3 调用BeanPostProcessor#postProcessAfterInitialization(初始化后的hook,AOP相关实现
  5. 注册destory相关方法(AbstractBeanFactory#registerDisposableBeanIfNecessary
  6. 完成创建,放入一级缓存。同时移除三级缓存和二级缓存中的相关对象