Spring Bean的生命周期探究

目录

前言

一、Spring Bean的作用域

二、Spring IOC容器的启动流程

三、Spring Bean的生命周期

四、总结 


前言

一直对Spring Bean的生命周期没有完全了解吃透,这次下定决定去好好看看源码,了解一下Bean的生命周期。先附上生命周期图,后续会详细从源码层面进行解析~

 

一、Spring Bean的作用域

  • Singleton :单例bean,唯一bean实例 (Spring中的bean默认都是单例的)

  • Prototype :原型bean,每一次请求都会创建一个新的bean

  • Request :每一次Http请求都会创建一个bean,仅在当前Http Request中有效

  • Session :每一次Http请求都会创建一个bean,仅在当前Http Session中有效

  • Global-session :全局session中有效

Spring中的Bean默认都是单例的,通常所说的Spring Bean的生命周期主要是指Singleton bean (即单例bean)。

二、Spring IOC容器的启动流程

通常所说的Spring的IOC容器是指BeanFactory(简单容器)和ApplicationContext(高级容器),ApplicationContext是BeanFactory的子接口,且BeanFactory是Spring IOC容器的最底层接口,只提供IOC容器最基本的功能,给具体的IOC容器的实现提供了规范,主要是负责配置、生产和管理bean,其内部定义了对单个bean的获取,对bean的作用域判断,获取bean类型,获取bean别名等功能。ApplicationContext包含BeanFactory的所有功能,同时它又继承了MessageSource、ListableBeanFactory、ResourceLoader、ApplicationEventPublisher等接口,为BeanFactory赋予了更高级的IOC容器特性。IOC容器具体由BeanFactory的子类DefaultListableBeanFactory类来实现。

 Spring IOC容器的启动流程的入口是:AbstractApplicationContext类中的refresh()方法,refresh()会将原本的ApplicationContext给销毁,然后重新执行一次初始化操作。

@Override
public void refresh() throws BeansException, IllegalStateException {
  synchronized (this.startupShutdownMonitor) {

    StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

    // step 1: 准备上下文进行刷新
    // 主要设置状态量(是否关闭,是否激活)
    // 记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
    // 以及校验必填属性是否配置及初始化用于存储早期应用事件的容器
    prepareRefresh();

    // step 2: 告诉子类去刷新内部的 Bean 工厂
    // 主要用于获取一个新的BeanFactory,如果BeanFactory已存在,则将其销毁并重建
    // 默认重建的BeanFactory为AbstractRefreshableApplicationContext
    // 这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

    // step 3: 准备 BeanFactory 以在此上下文中进行使用
    // 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 Bean
    prepareBeanFactory(beanFactory);

    try {
      // step 4: 允许在上下文子类中对 BeanFactory 进行后处理
      // 提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
      // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
      postProcessBeanFactory(beanFactory);

      StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");

      // step 5: 调用在上下文中被注册为 Bean 的工厂处理器
      // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
      invokeBeanFactoryPostProcessors(beanFactory);

      // step 6: 注册拦截创建 Bean 的 Bean 处理器
      // 注册 BeanPostProcessor 的实现类
      registerBeanPostProcessors(beanFactory);
      beanPostProcess.end();

      // step 7: 为此上下文初始化消息源
      initMessageSource();

      // step 8: 为此上下文初始化事件广播器
      initApplicationEventMulticaster();

      // step 9: 初始化特定上下文子类中的其他特殊 Bean
      // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
      onRefresh();

      // step 10: 检查并注册监听器 Bean
      registerListeners();

      // step 11: 实力化所有剩余的(非惰性初始化)的单例 Bean
      // Spring Bean 创建的流程入口
      // 初始化所有的非懒加载的 singleton beans
      finishBeanFactoryInitialization(beanFactory);

      // step 12: 发布相应的事件
      // ApplicationContext 初始化完成
      finishRefresh();
    }

    catch (BeansException ex) {
      if (logger.isWarnEnabled()) {
        logger.warn("Exception encountered during context initialization - " +
                    "cancelling refresh attempt: " + ex);
      }
      // step 13: 销毁bean 
      destroyBeans();
      cancelRefresh(ex);
      throw ex;
    }

    finally {
      resetCommonCaches();
      contextRefresh.end();
    }
  }
  • postProcessBeanFactory(beanFactory):在应用上下文内部的BeanFactory初始化结束后对其进行修改,在所有的BeanDefinition已被加载但还没有实例化bean, 此刻可以注册一些特殊的BeanPostFactory,如web应用会注册ServletContextAwareProcessor等。

  • registerBeanPostProcessors(beanFactory):实例化并注册BeanPostProcessor,如果有显式的顺序则按照顺序调用一定在所有bean实例化之前调用。

三、Spring Bean的生命周期

AbstractApplicationContext类中的refresh()方法的finishBeanFactoryInitialization(beanFactory)方法为Bean创建流程的入口,该方法负责创建所有非懒加载的单例Bean,并完成BeanFactory的初始化工作。

接下来从源码角度一步一步分析Spring Bean的创建流程(Bean的生命周期)。

首先,进入finishBeanFactoryInitialization(beanFactory)方法,该方法的还在AbstractApplicationContext类中(从第890行开始到919行结束),该方法的源码如下:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  // 初始化转换服务 为此上下文
  // ConversionService用于不同Class类型进行相互转换,比如String类型转为Boolean等
  // 最有用的场景就是,可以用来将前端传过来的参数和后端的Controller方法上的参数进行绑定的时候用
  if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
      beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
    beanFactory.setConversionService(
      beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
  }

  // 如果之前没有注册过任何 BeanFactoryPostProcessor
  // 则注册一个默认的嵌入值解析器,主要用于解析注释属性值。
  if (!beanFactory.hasEmbeddedValueResolver()) {
    beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
  }

  // 先初始化 LoadTimeWeaverAware 类型的 Bean (AspectJ的相关内容)
  String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
  for (String weaverAwareName : weaverAwareNames) {
    getBean(weaverAwareName);
  }

  // 停止使用临时 ClassLoader 进行类型匹配
  beanFactory.setTempClassLoader(null);

  // 关闭Bean的定义解析、加载、注册
  beanFactory.freezeConfiguration();

  // 实例化所有剩余的(非惰性初始化)单例
  // 核心方法 : 实例化Bean
  beanFactory.preInstantiateSingletons();
}

通过源码可以看出,finishBeanFactoryInitialization()方法主要是完成此上下文的BeanFactory的初始化工作,并初始化所有的单例Bean,其中的核心步骤是:

// ---###--- STEP.ONE : preInstantiateSingletons ---###---
beanFactory.preInstantiateSingletons();

preInstantiateSingletons()方法负责对所有非懒加载的单例Bean进行实例化。接着,进入到preInstantiateSingletons()方法,该方法在DefaultListableBeanFactory类中进行了实现(从第910行到第947行),该方法的源码如下:

public void preInstantiateSingletons() throws BeansException {

  // 打印日志
  if (logger.isTraceEnabled()) {
    logger.trace("Pre-instantiating singletons in " + this);
  }

  // beanDefinitionNames列表中保存了所有的Bean的Name
  // beanDefinitionNames在refresh()方法中的obtainFreshBeanFactory()方法中完成组装
  List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

  // 触发所有的非懒加载的 singleton beans 的初始化操作
  for (String beanName : beanNames) {
    // 合并当前Bean以及其父Bean的配置
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    // 针对非抽象 && 非懒加载 && 单例的Bean
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
      // 判断该Bean类型是否为FactoryBean
      // FactoryBean用于Bean的创建过程较为复杂的场景
      if (isFactoryBean(beanName)) {
        // 如果是FactoryBean,则在beanName前面加上 ‘&’ 符号
        // 调用getBean()获取Bean
        Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);

        // 判断当前FactoryBean是否是SmartFactoryBean的实现
        if (bean instanceof FactoryBean) {
          FactoryBean<?> factory = (FactoryBean<?>) bean;
          boolean isEagerInit;
          if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
            isEagerInit = AccessController.doPrivileged(
              (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
              getAccessControlContext());
          }
          else {
            isEagerInit = (factory instanceof SmartFactoryBean &&
                           ((SmartFactoryBean<?>) factory).isEagerInit());
          }
          if (isEagerInit) {
            getBean(beanName);
          }
        }

      }
      else {
        // 对于普通的Bean (非FactoryBean)
        // 根据当前遍历的beanName,获取Bean
        // 核心方法
        getBean(beanName);
      }
    }
  }

  // 为所有适用的Bean触发初始化后回调
  // 到这里说明所有的非懒加载的Singleton Beans都已经完成了初始化
  // 如果定义的Bean是实现了SmartInitializingSingleton接口,那么在这里得到回调
  for (String beanName : beanNames) {
    // 根据beanName获取单例Bean
    Object singletonInstance = getSingleton(beanName);
    // 检查Bean的类型是否为SmartInitializingSingleton
    if (singletonInstance instanceof SmartInitializingSingleton) {
      StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
        .tag("beanName", beanName);
      SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
      // 回调单例Bean实例化后的处理方法
      if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
          smartSingleton.afterSingletonsInstantiated();
          return null;
        }, getAccessControlContext());
      }
      else {
        smartSingleton.afterSingletonsInstantiated();
      }
      smartInitialize.end();
    }
  }
}

通过以上源码可以看出,preInstantiateSingletons()会遍历每一个beanName,并调用getBean(beanName)方法获取Bean,该方法中的核心方法是:

// ---###--- STEP.TWO : getBean ---###---
getBean(beanName);

Bean的初始化过程实际包含在getBean()方法中,该方法常用来从BeanFactory中获取一个具体的Bean。getBean()方法在AbstractBeanFactory类中(从第206行到第209行),其源码如下:

public Object getBean(String name) throws BeansException {
  // 核心方法
  return doGetBean(name, null, null, false);
}

getBean()方法中只有一个doGetBean()方法,毫无疑问,getBean方法的核心步骤就是:

// ---###--- STEP.THREE : doGetBean ---###---
return doGetBean(name, null, null, false);

下面直接进入到doGetBean()方法中,该方法也在AbstractBeanFactory类中(从第247行到第399行),主要用来返回指定Bean到一个实例,该实例可以是共享的(单例)也可以是独立的(原型)。对于已经初始化后的Bean就从容器中直接返回,否则会先初始化Bean后在返回。doGetBean()方法的源码如下:

doGetBean()方法的总共有4个参数:

  • @param: name  要检索的Bean的名称(beanName)

  • @param: requiredType  要检索的Bean的类型(beanType)

  • @param: args  使用显式参数创建Bean实例时使用的参数(仅在创建新实例而不是检索现有实例时应用)

  • @param: typeCheckOnly  是否获取实例进行类型检查,而不是实际使用

protected <T> T doGetBean(
  String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
  throws BeansException {

  // 规范化处理Bean的名称(beanName),统一格式
  // 比如:FactoryBean的名称前面会带 “&” 符号;
  // 有些Bean的名称还是别名(Alias)
  String beanName = transformedBeanName(name);
	// 需要返回的Bean实例(返回值)
  Object beanInstance;

  // 首先检查单例缓存以获取手动注册的单例
  // 检查beanName是否已经创建,先尝试从缓存中获取,若获取不到,就走下面的创建
  // 核心方法1
	// ---------------------------------- step 1 : start ----------------------------------
  Object sharedInstance = getSingleton(beanName);
  // 如果args不为空的时候,表示调用方不是希望获取Bean,而是创建Bean
  if (sharedInstance != null && args == null) {
    if (logger.isTraceEnabled()) {
      // 判断当前指定的Bean是否在创建过程中
      if (isSingletonCurrentlyInCreation(beanName)) {
        // 若条件为true,表示这个Bean虽然在缓存里,但是还并没有完全被初始化(循环引用)
        logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                     "' that is not fully initialized yet - a consequence of a circular reference");
      }
      else {
        logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
      }
    }
    // 获取指定Bean的实例(核心方法2)
    // 如果是普通的Bean,则直接返回sharedInstance
    // 如果是FactoryBean,则需要返回FactoryBean创建的实例对象
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  }
  // ----------------------------------- step 1 : end -----------------------------------

  else {
    // 如果已经在创建这个Bean实例,则失败(可能处于循环引用中)
    // 原型对象不允许循环创建,如果是原型对象正在创建,那就抛异常
    // ---------------------------------- step 2 : start ----------------------------------
    if (isPrototypeCurrentlyInCreation(beanName)) 
      // 创建过了此beanName的Prototype类型的Bean,则抛异常
      throw new BeanCurrentlyInCreationException(beanName);
    }

  	// 判断原型Bean是否在父容器中实例化过,避免被重复实例化(若父容器被实例化,就以父容器的为准)
    // 获取当前容器的父容器
    BeanFactory parentBeanFactory = getParentBeanFactory();
  	// 检查当前指定的Bean(beanName)的BeanDefinition是否存在于当前的beanDefinitionMap中
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
      // 如果在当前容器的beanDefinitionMap找不到beanName的BeanDefinition,则去父容器中找
      // 转换Bean的名称
      String nameToLookup = originalBeanName(name);
      // 从父容器中获取该Bean
      if (parentBeanFactory instanceof AbstractBeanFactory) {
        return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
          nameToLookup, requiredType, args, typeCheckOnly);
      }
      else if (args != null) {
        return (T) parentBeanFactory.getBean(nameToLookup, args);
      }
      else if (requiredType != null) {
        return parentBeanFactory.getBean(nameToLookup, requiredType);
      }
      else {
        return (T) parentBeanFactory.getBean(nameToLookup);
      }
    }
  ·// ---------------------------------- step 2 : end ----------------------------------

  	// 如果typeCheckOnly为false,则将当前beanName放入一个alreadyCreated的Set集合中
    // 表示该Bean已经创建了
    if (!typeCheckOnly) {
      markBeanAsCreated(beanName);
    }

  	// 开始执行Bean的实例化,也就是创建Bean
  	// 对于Singleton的Bean来说,容器中还没创建过此Bean
  	// 对于Prototype的Bean来说,本来就是要创建一个新的Bean
    StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
      .tag("beanName", name);
  
    try {
      
      if (requiredType != null) {
        beanCreation.tag("beanType", requiredType::toString);
      }
      
      // ---------------------------------- step 3 : start ----------------------------------
      // 合并当前Bean和其父Bean中的BeanDefinition
      RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
      // 检查mbd是否为抽象的或mbd为单例,但存在args的情况(args只有初始化原型对象才允许存在)
      checkMergedBeanDefinition(mbd, beanName, args);

      // 先初始化当前的Bean所依赖的所有其他的Beans
      // 因为会有属性注入等,所以这里就是要保证它依赖的那些属性先初始化才行
      // 这里的依赖指的是 depends-on 中定义的依赖
      String[] dependsOn = mbd.getDependsOn();
      
      if (dependsOn != null) {
        for (String dep : dependsOn) {
          // 检查当前Bean和依赖的Bean之间是否存在循环依赖
          // 如果出现循环依赖则抛出异常
          if (isDependent(beanName, dep)) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                            "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
          }
          // 注册当前Bean和依赖的Bean之间的依赖关系
          registerDependentBean(dep, beanName);
          try {
            // 先初始化依赖的Bean
            getBean(dep);
          }
          catch (NoSuchBeanDefinitionException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                            "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
          }
        }
      }
      // ---------------------------------- step 3 : end ----------------------------------

      // 创建Bean的实例
      // 如果是Singleton类型的Bean则创建Singleton的实例
      // ---------------------------------- step 4 : start ----------------------------------
      if (mbd.isSingleton()) 
        // 先尝试从缓存去获取,获取失败就通过ObjectFactory的createBean方法创建
        sharedInstance = getSingleton(beanName, () -> {
          try {
            // 执行Bean的创建过程
            // 核心方法3
            return createBean(beanName, mbd, args);
          }
          catch (BeansException ex) {
            // 创建过程如果出现异常需要销毁创建的Bean
            // 从单例缓存中显式删除该Bean实例:该实例可能已被创建,以允许循环引用解析
            // 还要删除任何接收到对该Bean的临时引用的Bean。
            destroySingleton(beanName);
            throw ex;
          }
        });
        // 核心方法2
        // 获取给定Bean的实例对象
        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
      }
  		// ---------------------------------- step 4 : end ----------------------------------

  		// --------------------------------- step 5 : start ---------------------------------
      else if (mbd.isPrototype()) {
        // 原型模式则创建一个新的Bean实例
        Object prototypeInstance = null;
        try {
          // 创建原型之前的回调
					// 默认实现将原型注册为当前正在创建中
          beforePrototypeCreation(beanName);
          // 创建原型Bean
          prototypeInstance = createBean(beanName, mbd, args);
        }
        finally {
          // 创建原型后的回调
					// 默认实现将原型标记为不再处于创建状态
          afterPrototypeCreation(beanName);
        }
        // 返回原型Bean实例对象
        beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
      }
  		// ---------------------------------- step 5 : end ----------------------------------

  		// --------------------------------- step 6 : start ---------------------------------
      else {
        // 如果不是Singleton和Prototype的话,需要委托给相应的实现类来处理
        String scopeName = mbd.getScope();
        if (!StringUtils.hasLength(scopeName)) {
          throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
        }
        Scope scope = this.scopes.get(scopeName);
        if (scope == null) {
          throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
        }
        try {
          Object scopedInstance = scope.get(beanName, () -> {
            beforePrototypeCreation(beanName);
            try {
              return createBean(beanName, mbd, args);
            }
            finally {
              afterPrototypeCreation(beanName);
            }
          });
          beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
        }
        // ---------------------------------- step 6 : end ----------------------------------
        catch (IllegalStateException ex) {
          throw new ScopeNotActiveException(beanName, scopeName, ex);
        }
      }
    }
    catch (BeansException ex) {
      beanCreation.tag("exception", ex.getClass().toString());
      beanCreation.tag("message", String.valueOf(ex.getMessage()));
      cleanupAfterBeanCreationFailure(beanName);
      throw ex;
    }
    finally {
      beanCreation.end();
    }
  }

	// 检查所需类型是否与实际Bean实例的类型匹配
	// 匹配则返回该Bean实例
	// ---------------------------------- step 7 : start ----------------------------------
  return adaptBeanInstance(name, beanInstance, requiredType);
	// ----------------------------------- step 7 : end -----------------------------------
}

 

Spring中真正创建Bean实例的逻辑就是在doGetBean()方法当中,该方法非常的长,总结一下就是:

  • step 1 : 尝试从单例缓存中获取单例Bean实例

  • step 2 : 对于Prototype类型的Bean需要进行循环依赖检查,并尝试获取原型Bean实例

  • step 3 : 创建Bean实例前的准备工作,先创建全部依赖的Beans,并进行Depends-on依赖的检查

  • step 4 : 创建Singleton类型的Bean实例

  • step 5 : 创建Prototype类型的Bean实例

  • step 6 : 创建其他类型的Bean实例

  • step 7 : 检查Bean的类型是否匹配

简单来说,首先从单例缓存中尝试获取单例Bean,如果缓存中有则返回;如果没有,则检查是否为原型Bean,对于原型Bean需要进行循环依赖检查,原型Bean不允许循环创建,检查原型Bean是否已经在父容器中实例化过,并尝试获取,如果获取失败,此时表明Spring的IOC容器中没有该Bean,因此接下来需要创建该Bean的实例。对于Singleton类型Bean来说,容器还没有创建过,而对于Prototype类型的Bean来说,容器本来就需要创建一个新的Bean。创建Bean前需要做一些准备工作,即保证待创建的Bean的所有依赖的其他Beans都已经创建好,待所有依赖的Beans创建好后,开始创建该Bean。接下来就是根据Bean的类型走具体的创建方法。最后对创建的Bean进行类型检查后返回创建的Bean实例。

从doGetBean()方法的源码也可以看出,该方法中包含三个核心的步骤:

// getSingleton() : 获取单例Bean 
// ---###--- STEP.FOUR : getSingleton ---###---
Object sharedInstance = getSingleton(beanName);
// getObjectForBeanInstance() : 获取给定Bean实例对象
// ---###--- STEP.FIVE : getObjectForBeanInstance ---###---
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
// createBean() : 创建Bean实例
// ---###--- STEP.SIX : createBean ---###---
createBean(beanName, mbd, args);

接下来依次来看看这三个核心步骤,首先进入到getSingleton()方法中,该方法在DefaultSingleBeanRegistry类中(第165行到第204行),其源码如下:

getSingleton()方法的两个参数:

  • @param :  beanName  要查找的Bean的名称

  • @param :  allowEarlyReference  是否应该创建早期引用(也就是是否要加入到二级缓存)

doGetBean()源码中第256行(本文第16行)调用的getSingleton()方法:

public Object getSingleton(String beanName) {
  return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  // 尝试从单例缓存(也就是一级缓存)获取Bean
  Object singletonObject = this.singletonObjects.get(beanName);
  // 一级缓存中没有,则判断当前Bean是否正在创建过程中
  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    // 尝试从二级缓存获取Bean
    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) {
            // 从三级缓存获取该Bean的单例工厂(可以创建该Bean的工厂)
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
              // 利用工厂创建该Bean
              singletonObject = singletonFactory.getObject();
              // 将该Bean对象加入到二级缓存中
              this.earlySingletonObjects.put(beanName, singletonObject);
              // 删除三级缓存中该Bean的单例工厂
              this.singletonFactories.remove(beanName);
            }
          }
        }
      }
    }
  }
  return singletonObject;
}

doGetBean()源码中第333行(本文第127行)调用的getSingleton()方法:

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  Assert.notNull(beanName, "Bean name must not be null");
  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!)");
      }
      if (logger.isDebugEnabled()) {
        logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
      }

      // 创建前置检查:
      // 		1、是否在当前创建检查的排除名单inCreationCheckExclusions里?
      // 		2、正在创建的Bean名称集合singletonsCurrentlyInCreation是包含该Bean?不包含则添加进去(表明该Bean在创建中)
      // 只有当前Bean包含在inCreationCheckExclusions中,
      // 或者包含在singletonsCurrentlyInCreation中才OK
      beforeSingletonCreation(beanName);
      boolean newSingleton = false;
      boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
      if (recordSuppressedExceptions) {
        this.suppressedExceptions = new LinkedHashSet<>();
      }
      try {
        // 通过单例工厂创建该Bean对象
        singletonObject = singletonFactory.getObject();
        // 标记该Bean为新对象
        newSingleton = true;
      }
      catch (IllegalStateException ex) {
        // Bean创建失败,而这个Bean却已经放在了一级缓存中,则抛出这个异常吧
        singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
          throw ex;
        }
      }
      catch (BeanCreationException ex) {
        if (recordSuppressedExceptions) {
          for (Exception suppressedException : this.suppressedExceptions) {
            ex.addRelatedCause(suppressedException);
          }
        }
        throw ex;
      }
      finally {
        if (recordSuppressedExceptions) {
          this.suppressedExceptions = null;
        }
        // 创建完成后检查:
        //		1. 是否在当前创建检查的排除名单inCreationCheckExclusions里?
        //		2. 是否从正在创建的Bean名称集合singletonsCurrentlyInCreation中移除了该Bean?
        afterSingletonCreation(beanName);
      }

      // 判断是否为新的Bean
      if (newSingleton) {
        // addSingleton()方法:
        // 		this.singletonObjects.put(beanName, singletonObject); 加入一级缓存
        // 		this.singletonFactories.remove(beanName); 清除三级缓存中该Bean的单例工厂
        // 		this.earlySingletonObjects.remove(beanName);  清除二级缓存中该Bean
        // 		this.registeredSingletons.add(beanName); 已经注册的单例Bean集合添加该Bean
        addSingleton(beanName, singletonObject);
      }
    }
    return singletonObject;
  }
}

这里需要介绍一下Spring中的三级缓存的概念。三级缓存的存在主要是用来解决循环依赖的问题,这三级缓存分别是:

/** Cache of singleton objects: bean name --> bean instance */
/** 一级缓存 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

/** Cache of early singleton objects: bean name --> bean instance */
/** 二级缓存 */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

/** Cache of singleton factories: bean name --> ObjectFactory */
/** 三级缓存 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
  • 一级缓存 singletonObjects:单例对象缓存,保存的是所有已经被实例化,初始化之后,也就是完全创建完成之后的单例Bean对象;

  • 二级缓存 earlySingletonObjects:早期单例对象缓存,保存的是已经被实例化,但是还没有完成属性注入的早期暴露的Bean对象。由于此时的单例Bean对象还没有完成初始化,也就是没有真正创建完成,所以此时的Bean不会存在于一级缓存中;

  • 三级缓存 singletonFactories:单例工厂缓存,保存的是可以用来创建Bean的工厂。如果一个Bean在一级和二级缓存中都没有,但是三级缓存中有能够创建该Bean的单例工厂,则可以通过三级缓存获取该工厂来创建Bean,并将该Bean存入二级缓存,同时会将该工厂从三级缓存中删除。

所以,获取一个单例Bean的流程是(也就是getSingleton()方法的执行流程):首先从一级缓存中尝试获取Bean,如果一级缓存有,说明该Bean已经创建好了,直接返回即可。如果一级缓存没有,则需要检查当前的Bean是否在创建过程中,如果是,表明当前Bean还没有创建好(没创建好则一级缓存中肯定没有),此时尝试从二级缓存中获取该Bean,如果二级缓存有,则直接返回,否则,判断是否允许将单例工厂创建的早期Bean加入到二级缓存,如果允许,则尝试从三级缓存获取该Bean的单例工厂,通过单例工厂来创建该Bean,并添加到二级缓存中,同时删除三级缓存中的单例工厂,并返回创建Bean。

另外需要注意的是,getSingleton()方法中使用了单例模式的双重检查锁定,即:首先从缓存中获取Bean实例,如果为Null,则对缓存Map加锁,然后再从缓存中获取bean,如果继续为Null,就创建一个Bean。这样双重判断,能够避免在加锁的瞬间,有其他依赖注入引发Bean实例的创建,从而造成重复创建的结果。

接下来看看getObjectForBeanInstance()方法,该方法在AbstractBeanFactory类中(第1845行到1887行),简单理解就是处理FactoryBean的getObject()方法,如果是普通的Bean,则直接返回sharedInstance,如果是FactoryBean,则需要返回FactoryBean创建的实例对象。getObjectForBeanInstance()方法的源码如下:

getObjectForBeanInstance()方法的两个参数:

  • @param :  beanInstance   Bean实例

  • @param :  name  格式化之前的beanName

  • @param :  beanName  格式化之后的beanName

  • @param :  mbd   合并父Bean后的定义 

protected Object getObjectForBeanInstance(
  Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

  // 判断name是否以 “&” 开头
  // 如果该Bean不是工厂,不要让调用代码尝试取消对工厂的引用。
  if (BeanFactoryUtils.isFactoryDereference(name)) {
    if (beanInstance instanceof NullBean) {
      return beanInstance;
    }
    // 判断Bean是否为FactoryBean类型
    if (!(beanInstance instanceof FactoryBean)) {
      throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
    }
    if (mbd != null) {
      mbd.isFactoryBean = true;
    }
    return beanInstance;
  }

  // 现在我们有了Bean实例,它可能是普通的Bean或FactoryBean
  // 如果它是一个FactoryBean,则使用它来创建一个Bean实例,除非调用者实际上想要一个对工厂的引用。
  if (!(beanInstance instanceof FactoryBean)) {
    return beanInstance;
  }

  Object object = null;
  if (mbd != null) {
    mbd.isFactoryBean = true;
  }
  else {
    // 尝试从FactoryBean缓存中获取Bean
    object = getCachedObjectForFactoryBean(beanName);
  }
  if (object == null) {
    // 获取失败则通过FactoryBean创建Bean
    FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
    // 合并父Bean的定义
    if (mbd == null && containsBeanDefinition(beanName)) {
      mbd = getMergedLocalBeanDefinition(beanName);
    }
    boolean synthetic = (mbd != null && mbd.isSynthetic());
    // 从给定的FactoryBean中获取要公开的对象
    object = getObjectFromFactoryBean(factory, beanName, !synthetic);
  }
  return object;
}

从给定的FactoryBean中获取要公开的Bean对象getObjectFromFactoryBean()方法就不细说了,总之只需要知道getObjectForBeanInstance()方法就是用来判断beanInstance是Bean实例还是FactoryBean,如果是Bean实例则直接返回,否则会调用FactoryBean的getObject()方法获取Bean实例后在返回。

接下来是doGetBean()方法中最核心的部分:createBean()方法,该方法的实现在AbstractAutowireCapableBeanFactory类中(第484行到第540行),主要进行创建Bean实例、填充Bean实例、应用后处理器等。该类的源码如下:

createBean()方法的两个参数:

  • @param :  beanName  Bean的名称

  • @param :  mbd   合并父Bean后的定义

  • @param :  args   创建实例需要的参数(构造方法用的参数或工厂Bean的参数) 

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  throws BeanCreationException {

  if (logger.isTraceEnabled()) {
    logger.trace("Creating instance of bean '" + beanName + "'");
  }
  RootBeanDefinition mbdToUse = mbd;

  // 确保BeanDefinition中的Class已经被加载
  // 为指定的Bean定义解析Bean的类(resolvedClass)
  // 将Bean类名称解析为Class引用并将解析的Class存储在Bean定义中以供进一步使用
  Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    mbdToUse = new RootBeanDefinition(mbd);
    mbdToUse.setBeanClass(resolvedClass);
  }

  // 准备方法重写
  try {
    // 主要是解析lookup-method和replace-method这两种依赖注入方式
    // 相当于调用指定类里面的指定方法进行注入,所以需要考虑到方法重载的情况
    mbdToUse.prepareMethodOverrides();
  }
  catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                                           beanName, "Validation of method overrides failed", ex);
  }

  try {
    // 让BeanPostProcessors有机会返回一个代理而不是目标Bean实例 (实现Spring动态代理的地方)
    // 方法的执行逻辑:
    //  1、判断当前Spring容器是否注册实现了InstantiationAwareBeanPostProcessor接口,如果是则依次调用其中的方法
    //  2、判读是否注册实现了BeanPostProcessor接口,如果是则依次调用其中的方法
    // 如果实现了上述的两个接口后,这里返回的就是Bean的代理对象
    // 核心方法1
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    // 如果不为空,说明提前生成了实例,直接返回
    if (bean != null) {
      return bean;
    }
  }
  catch (Throwable ex) {
    throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                                    "BeanPostProcessor before instantiation of bean failed", ex);
  }

  try {

    // 核心方法2
    // 创建Bean实例
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isTraceEnabled()) {
      logger.trace("Finished creating instance of bean '" + beanName + "'");
    }
    // 创建完成后 直接短路掉返回
    return beanInstance;
  }
  catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
    // A previously detected exception with proper bean creation context already,
    // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
    throw ex;
  }
  catch (Throwable ex) {
    throw new BeanCreationException(
      mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  }
}

通过createBean()的源码可以看出,有两个非常重要的核心步骤,分别是:

// 让BeanPostProcessors有机会返回一个代理而不是目标Bean实例
// ---###--- STEP.SEVEN : resolveBeforeInstantiation ---###---
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 创建Bean实例
// ---###--- STEP.EIGHT : doCreateBean ---###---
Object beanInstance = doCreateBean(beanName, mbdToUse, args);

先看一下resolveBeforeInstantiation()方法,该方法在AbstractAutowireCapableBeanFactory类中(第1110行到第1126行),主要做用于Bean的实例化之前执行,在实例化前应用后处理器,解析指定 bean 是否存在实例化前快捷方式。其源码如下:

resolveBeforeInstantiation()方法的两个参数:

  • @param :  beanName  Bean的名称

  • @param :  mbd   合并父Bean后的定义

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  Object bean = null;
  // 如果是false,表示不需要进行前置处理
  if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    // 确保Bean Class在里已经被解析
    // 检查容器里是否有InstantiationAwareBeanPostProcessor接口的实现
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      // 获取最终的Bean类型
      Class<?> targetType = determineTargetType(beanName, mbd);
      if (targetType != null) {
        // 执行InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation回调方法
        // 拿到缓存好的所有的BeanPostProcessors,如果是InstantiationAwareBeanPostProcessor就执行
        // 只要有一个result不为null,则后面的所有 后置处理器 都不执行了,直接返回
        // 核心方法1
        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    
        if (bean != null) {
          // 初始化完成后执行的方法(初始化的后置方法),属于BeanPostProcessor
          // 即使Bean在实例化前已经返回了一个不为null的对象,别的方法都被短路了,
          // 但是applyBeanPostProcessorsAfterInitialization还是可以执行的
          // 核心方法2
          bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
        }
      }
    }
    mbd.beforeInstantiationResolved = (bean != null);
  }
  return bean;
}

 resolveBeforeInstantiation()方法中有两个核心的步骤,分别是:

// 调用InstantiationAwareBeanPostProcessors接口的postProcessBeforeInstantiation方法
// 在Bean实例化前执行,返回的是代理Bean对象
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
// 调用BeanPostProcessor接口的postProcessAfterInitialization方法
// 在Bean初始化后执行
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);

applyBeanPostProcessorsBeforeInstantiation()方法以及applyBeanPostProcessorsAfterInitialization()方法的源码如下,这两个方法的实现都在AbstractAutowireCapableBeanFactory类中,分别在(第1139行到第1148行)和(第432行到第444行):

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
  for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
    // 执行InstantiationAwareBeanPostProcessors接口的postProcessBeforeInstantiation方法
    Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
    // 如果result不为null,就直接返回了,后面的bp都不会执行了
    if (result != null) {
      return result;
    }
  }
  return null;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  throws BeansException {

  // 此时的Bean已经实例化完成
  Object result = existingBean;
  // 对已经实例化的Bean调用BeanPostProcessor的postProcessAfterInitialization方法
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
    Object current = processor.postProcessAfterInitialization(result, beanName);
    if (current == null) {
      return result;
    }
    result = current;
  }
  return result;
}

需要注意的是:

  • 实例化:实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中

  • 初始化:初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性

InstantiationAwareBeanPostProcessor是作用于 实例化 前后,所以是先执行的;BeanPostProcessor是作用于 初始化 前后,给Bean各个属性赋值的时候执行的。

接着看doCreateBean()方法,该方法同样位于AbstractAutowireCapableBeanFactory类中(第555行到第651行),其源码如下:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  throws BeanCreationException {

  // 实例化Bean
  // 用BeanWrapper来持有创建出来的Bean对象
  BeanWrapper instanceWrapper = null;
  if (mbd.isSingleton()) 
    // 如果是单例的话,则先把缓存中的同名Bean清除
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  }
  if (instanceWrapper == null) {
    // 实际负责创建Bean的方法
    // 核心方法1
    instanceWrapper = createBeanInstance(beanName, mbd, args);
  }
	// 获取由BeanWrapper对象包装的Bean实例
  Object bean = instanceWrapper.getWrappedInstance();
	// 获取Bean实例的类型
  Class<?> beanType = instanceWrapper.getWrappedClass();
	// 处理NullBean类
  if (beanType != NullBean.class) {
    mbd.resolvedTargetType = beanType;
  }

  // 允许后处理器修改合并的Bean定义
  synchronized (mbd.postProcessingLock) {
    if (!mbd.postProcessed) {
      try {
        // 由MergedBeanDefinitionPostProcessor进行处理
        // 主要处理@PostConstruct, @Autowire, @Value, @Resource, @PreDestory等注解
        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      }
      catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                        "Post-processing of merged bean definition failed", ex);
      }
      mbd.postProcessed = true;
    }
  }

  // 如果当前Bean是单例,且支持循环依赖,且当前bean正在创建
	// 通过往singletonFactories添加一个objectFactory
	// 这样后期如果有其他Bean依赖该Bean 可以从singletonFactories获取到Bean
  boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                    isSingletonCurrentlyInCreation(beanName));
  if (earlySingletonExposure) {
    if (logger.isTraceEnabled()) {
      logger.trace("Eagerly caching bean '" + beanName +
                   "' to allow for resolving potential circular references");
    }
    // 解决循环依赖问题
    // SmartInstantiationAwareBeanPostProcessor
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  }

  // 初始化Bean实例
	// 最终要返回的Bean对象
  Object exposedObject = bean;
  try {
    // 核心方法2
    // 给Bean进行属性赋值,完成依赖注入
    populateBean(beanName, mbd, instanceWrapper);
    // 完成属性依赖注入后,进一步初始化Bean
    // 核心方法3
    exposedObject = initializeBean(beanName, exposedObject, mbd);
  }
  catch (Throwable ex) {
    if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
      throw (BeanCreationException) ex;
    }
    else {
      throw new BeanCreationException(
        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
    }
  }

	// 如果为true则尝试从缓存中获取Bean
  if (earlySingletonExposure) {
    Object earlySingletonReference = getSingleton(beanName, false);
    // 如果能获取到该Bean对象
    // 则修改exposedObject的引用为从缓存获取到的Bean
    if (earlySingletonReference != null) {
      if (exposedObject == bean) {
        exposedObject = earlySingletonReference;
      }
      else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
        String[] dependentBeans = getDependentBeans(beanName);
        Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
        for (String dependentBean : dependentBeans) {
          if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
            actualDependentBeans.add(dependentBean);
          }
        }
        if (!actualDependentBeans.isEmpty()) {
          throw new BeanCurrentlyInCreationException(beanName,
                                                     "Bean with name '" + beanName + "' has been injected into other beans [" +
                                                     StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                                     "] in its raw version as part of a circular reference, but has eventually been " +
                                                     "wrapped. This means that said other beans do not use the final version of the " +
                                                     "bean. This is often the result of over-eager type matching - consider using " +
                                                     "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
        }
      }
    }
  }

  // 注册DisposableBean
	// 在Bean需要销毁的时候会调用相关的后处理器进行处理
  try {
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
  }
  catch (BeanDefinitionValidationException ex) {
    throw new BeanCreationException(
      mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  }

  return exposedObject;
}

通过源码可以看出doCreateBean()方法中有三个很核心的方法,分别是:

// 实际负责创建Bean的方法
// ---###--- STEP.NINE : createBeanInstance ---###---
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 属性赋值
// ---###--- STEP.TEN : populateBean ---###---
populateBean(beanName, mbd, instanceWrapper);
// 完成Bean的初始化
// ---###--- STEP.THIRTEEN : initializeBean ---###---
exposedObject = initializeBean(beanName, exposedObject, mbd);

先来看看createBeanInstance()方法,该方法位于AbstractAutowireCapableBeanFactory类的(第1162行到第1215行),使用适当的实例化策略为指定的 Bean创建一个新实例:工厂方法、构造函数自动装配或简单实例化,其源码如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
  // 确保bean类实际上已经解析过了,可以实例化
  Class<?> beanClass = resolveBeanClass(mbd, beanName);

  // 确保beanClass不空,且为public,且允许访问非公共构造函数和方法 
  // 如果beanClass不是public类型,则创建不了对象
  if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
  }

  // 配置的一种特殊的callback回调方法,通过这个callback创建bean
  // Supplier返回的对象,最终会交给obtainFromSupplier包装成BeanWrapper 
  Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
  if (instanceSupplier != null) {
    return obtainFromSupplier(instanceSupplier, beanName);
  }

  // 使用工厂方法来进行Bean的实例化
  if (mbd.getFactoryMethodName() != null) {
    return instantiateUsingFactoryMethod(beanName, mbd, args);
  }

  // 一个类可能有多个构造器,得根据参数个数、类型确定需要调用的构造器
  
  boolean resolved = false;
  boolean autowireNecessary = false;
  if (args == null) {
    synchronized (mbd.constructorArgumentLock) {
      // 用于缓存解析的构造函数或工厂方法 非空
      if (mbd.resolvedConstructorOrFactoryMethod != null) {
        // 标记已经解析beanClass的构造器
        resolved = true;
        // 将构造函数参数标记为已解析
        autowireNecessary = mbd.constructorArgumentsResolved;
      }
    }
  }
  
  // 已经解析过构造器,直接使用解析好的构造器实例化Bean
  if (resolved) {
    if (autowireNecessary) {
      // 构造函数依赖注入
      // 核心方法1
      return autowireConstructor(beanName, mbd, null, null);
    }
    else {
      // 调用无参构造函数进行实例化
      // 核心方法2
      return instantiateBean(beanName, mbd);
    }
  }

  // 判断是否采用有参构造函数
  // 如果Bean没有空的构造函数,则会用这个构造函数实例化Bean,且入参会自动从容器里去找出来)
  Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
      mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
    // 构造函数依赖注入,调用有餐构造函数
    return autowireConstructor(beanName, mbd, ctors, args);
  }

  // 判断默认构造的是不是首选构造函数
  ctors = mbd.getPreferredConstructors();
  if (ctors != null) {
    return autowireConstructor(beanName, mbd, ctors, null);
  }

  // 没有特殊处理:只需使用无参数构造函数
  return instantiateBean(beanName, mbd);
}

重点关注一下createBeanInstance()方法中的两个核心方法:

// 获取被包装后的Bean,包装后的对象是BeanWrapper对象
// 包含被封装后待处理的bean,和设置bean属性的属性编辑器
// ---###--- STEP.ELEVEN : autowireConstructor ---###---
protected BeanWrapper autowireConstructor(
  String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

  return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
// 默认的无参构造方法实例化Bean
// ---###--- STEP.TWELVE : instantiateBean ---###---
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
  try {
    Object beanInstance;
    if (System.getSecurityManager() != null) {
      beanInstance = AccessController.doPrivileged(
        (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
        getAccessControlContext());
    }
    else {
      // 采用实例化策略来创建Bean
      // 通过反射获取构造器来创建Bean
      // 核心方法
      beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
    }
    // 包装bean
    BeanWrapper bw = new BeanWrapperImpl(beanInstance);
    initBeanWrapper(bw);
    return bw;
  }
  catch (Throwable ex) {
    throw new BeanCreationException(
      mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
  }
}

在instantiateBean()方法中的核心步骤:

// ---###--- STEP.THIRTEEN : getInstantiationStrategy().instantiate ---###---
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);

中,通过反射的方式去获取到beanClass的默认无参构造器(getDeclaredConstructor()),调用newInstance()方法完成Bean实例的创建,至此,Bean的实例化完成,Bean已经成功创建了出来,但是此时的Bean还没有进行赋值,属性都是默认值,下一步就需要给Bean的属性进行赋值操作。

接下来就是Bean的初始化操作,首先就是为Bean的各个属性进行赋值操作。接着来看一下populateBean()方法,该方法同样位于AbstractAutowireCapableBeanFactory类中,(从第1365行到第1436行),其源码如下:

populateBean()方法的两个参数:

  • @param :  beanName  Bean的名称

  • @param :  mbd   合并父Bean后的定义

  • @param :bw  带有 bean 实例的 BeanWrapper

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  
  if (bw == null) {
    // 是否有为此Bean定义的属性值
    if (mbd.hasPropertyValues()) {
      throw new BeanCreationException(
        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
    }
    else {
      // 该实例没有属性值,则跳过赋值阶段
      return;
    }
  }

  // 让任何InstantiationAwareBeanPostProcessors有机会在设置属性之前修改Bean的状态
  // 具体通过调用postProcessAfterInstantiation方法
  if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
      // 如果调用返回false,表示不必继续进行依赖注入,直接返回
      // 只有返回true,后面的处理器才会继续执行
      if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
        return;
      }
    }
  }

  // 获取还Bean的属性值
  PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

  // 根据Bean配置的依赖注入方式完成注入
  int resolvedAutowireMode = mbd.getResolvedAutowireMode();
  // 判断依赖注入方式是 By_name 还是 By_type (根据名称注入还是根据类型注入)
  if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    // 深拷贝当前已有的属性值
    MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    // 根据名称进行依赖注入
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
      autowireByName(beanName, mbd, bw, newPvs);
    }
    // 根据类型进行依赖注入
    if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      autowireByType(beanName, mbd, bw, newPvs);
    }
    // 结合注入后的配置,覆盖当前配置
    pvs = newPvs;
  }

  // 是否存在InstantiationAwareBeanPostProcessor处理器
  boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
  // 是否进行依赖检查,默认为None
	// 可以使用@Required注解进行控制,作用于setter()方法上,用于检查一个Bean的属性的值在配置期间是否被赋予或设置
  boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

  // 所有需要进行依赖检查的属性编辑器
  PropertyDescriptor[] filteredPds = null;
  if (hasInstAwareBpps) {
    if (pvs == null) {
      // 获取属性值
      pvs = mbd.getPropertyValues();
    }
    
    // 调用了InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法
    // 在工厂将给定的属性值应用到给定的Bean之前 对其进行后处理
    for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
      PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
      if (pvsToUse == null) {
        if (filteredPds == null) {
          // 过滤出所有需要进行依赖检查的属性编辑器
          filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        // 对采用 @Autowired、@Value 注解的依赖进行设值
        // 关键的后处理器:AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor
        pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
        if (pvsToUse == null) {
          return;
        }
      }
      pvs = pvsToUse;
    }
  }
  if (needsDepCheck) {
    if (filteredPds == null) {
      filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    }
    // 执行依赖项检查以确保所有公开的属性都已设置
    checkDependencies(beanName, mbd, filteredPds, pvs);
  }

  if (pvs != null) {
    // 设置Bean的属性值
    // 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中
    // 核心方法
    applyPropertyValues(beanName, mbd, bw, pvs);
  }
}

 在populateBean()方法中真正完成属性赋值的方式是applyPropertyValues()方法,同样在AbstractAutowireCapableBeanFactory类中,(从第1635行到第1728行),其源码如下:

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
  if (pvs.isEmpty()) {
    return;
  }

  if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
    ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
  }

  MutablePropertyValues mpvs = null;
  List<PropertyValue> original;

  if (pvs instanceof MutablePropertyValues) {
    mpvs = (MutablePropertyValues) pvs;
    if (mpvs.isConverted()) {
      // Shortcut: use the pre-converted values as-is.
      try {
        bw.setPropertyValues(mpvs);
        return;
      }
      catch (BeansException ex) {
        throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Error setting property values", ex);
      }
    }
    original = mpvs.getPropertyValueList();
  }
  else {
    original = Arrays.asList(pvs.getPropertyValues());
  }

  TypeConverter converter = getCustomTypeConverter();
  if (converter == null) {
    converter = bw;
  }
  BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

  // Create a deep copy, resolving any references for values.
  List<PropertyValue> deepCopy = new ArrayList<>(original.size());
  boolean resolveNecessary = false;
  for (PropertyValue pv : original) {
    if (pv.isConverted()) {
      deepCopy.add(pv);
    }
    else {
      String propertyName = pv.getName();
      Object originalValue = pv.getValue();
      if (originalValue == AutowiredPropertyMarker.INSTANCE) {
        Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
        if (writeMethod == null) {
          throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
        }
        originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
      }
      Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
      Object convertedValue = resolvedValue;
      boolean convertible = bw.isWritableProperty(propertyName) &&
        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
      if (convertible) {
        convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
      }
      // Possibly store converted value in merged bean definition,
      // in order to avoid re-conversion for every created bean instance.
      if (resolvedValue == originalValue) {
        if (convertible) {
          pv.setConvertedValue(convertedValue);
        }
        deepCopy.add(pv);
      }
      else if (convertible && originalValue instanceof TypedStringValue &&
               !((TypedStringValue) originalValue).isDynamic() &&
               !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
        pv.setConvertedValue(convertedValue);
        deepCopy.add(pv);
      }
      else {
        resolveNecessary = true;
        deepCopy.add(new PropertyValue(pv, convertedValue));
      }
    }
  }
  if (mpvs != null && !resolveNecessary) {
    mpvs.setConverted();
  }

  // Set our (possibly massaged) deep copy.
  try {
    bw.setPropertyValues(new MutablePropertyValues(deepCopy));
  }
  catch (BeansException ex) {
    throw new BeanCreationException(
      mbd.getResourceDescription(), beanName, "Error setting property values", ex);
  }
}

在完成属性的赋值之后,接下来需要完成的就是Bean的初始化工作,开始执行initializeBean()方法。initializeBean()方法同样位于AbstractAutowireCapableBeanFactory类中,(从第1765行到第1794行),主要作用是初始化给定的 bean 实例,应用工厂回调以及 init 方法和 bean 后处理器。该方法的源码如下:

initializeBean()方法的两个参数:

  • @param :  beanName  Bean的名称

  • @param :  bean   需要初始化的Bean

  • @param :mbd  创建 bean 的 bean 定义(也可以是null ,如果给定一个现有的 bean 实例)

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
  
  // 执行全部的Aware的方法
  // 比如:BeanNameAware、BeanClassLoaderAware等
  if (System.getSecurityManager() != null) {
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
      invokeAwareMethods(beanName, bean);
      return null;
    }, getAccessControlContext());
  }
  else {
    // 核心方法1
    invokeAwareMethods(beanName, bean);
  }

  Object wrappedBean = bean;
  if (mbd == null || !mbd.isSynthetic()) {
    // 调用BeanPostProcessor的postProcessBeforeInitialization
    // 在初始化之前执行
    // 核心方法2
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  }

  try {
    // 处理Bean中定义的init-method
    // 或者如果Bean实现了InitializingBean接口,则调用afterPropertiesSet()方法
    // 这里init-method方法的名称不能是afterPropertiesSet,并且这个类不是InitializingBean类型才会调用
    // 核心方法3
    invokeInitMethods(beanName, wrappedBean, mbd);
  }
  catch (Throwable ex) {
    throw new BeanCreationException(
      (mbd != null ? mbd.getResourceDescription() : null),
      beanName, "Invocation of init method failed", ex);
  }
  if (mbd == null || !mbd.isSynthetic()) {
    // 调用BeanPostProcessor的postProcessAfterInitialization方法
    // 在Bean初始化完成后执行
    // 核心方法4
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  }

  return wrappedBean;
}

 通过上述的源码可以看出,initializeBean()方法当中有4个比较重要的方法,分别是:

// 调用实现了Aware接口的方法
// ---###--- STEP.FOURTEEN : invokeAwareMethods ---###---
invokeAwareMethods(beanName, bean);
// 在初始化前调用后处理器方法
// ---###--- STEP.FIFTEEN : applyBeanPostProcessorsBeforeInitialization ---###---
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// 调用afterPropertiesSet()方法或则init-method方法
// ---###--- STEP.SIXTEEN : invokeInitMethods ---###---
invokeInitMethods(beanName, wrappedBean, mbd);
// 在初始化之后执行后处理器方法
// ---###--- STEP.SEVENTEEN : applyBeanPostProcessorsAfterInitialization ---###---
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

接下来接着看看这4个核心的步骤,首先看看invokeAwareMethods()方法,主要就是调用该Bean实现的各种Aware接口中的方法进行各种属性设置,该方法位于AbstractAutowireCapableBeanFactory类中,(从第1796行到第1811行),源码如下:

invokeAwareMethods()方法的两个参数:

  • @param :  beanName  Bean的名称

  • @param :  bean   需要初始化的Bean

private void invokeAwareMethods(String beanName, Object bean) {
  // 判断Bean是否实现Aware接口
  if (bean instanceof Aware) {
    // 调用BeanNameAware的setBeanName方法设置Bean的名称
    if (bean instanceof BeanNameAware) {
      ((BeanNameAware) bean).setBeanName(beanName);
    }
    // 调用BeanClassLoaderAware的setBeanClassLoader方法设置Bean的类加载器
    if (bean instanceof BeanClassLoaderAware) {
      ClassLoader bcl = getBeanClassLoader();
      if (bcl != null) {
        ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
      }
    }
    // 调用BeanFactoryAware的setBeanFactory设置Bean的工厂
    if (bean instanceof BeanFactoryAware) {
      ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
    }
  }
}

 接下来的两个方法:applyBeanPostProcessorsBeforeInitialization()和applyBeanPostProcessorsAfterInitialization()方法就不多介绍了,主要是进行Bean初始化前后的一些回调处理。两个方法都位于AbstractAutowireCapableBeanFactory类中,分别位于(第417行到第429行)和(从第432行到第444行)。需要注意的是,这两个方法在依次调用BeanPostProcessor后处理器进行处理时,如果有一个返回了null对象,则直接返回,不再调用后面的后处理器方法了。另外,调用后处理器方法返回的是代理的Bean对象。下面附上这两个方法的源码,具体不解释了!

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
  throws BeansException {

  Object result = existingBean;
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
    Object current = processor.postProcessBeforeInitialization(result, beanName);
    // 一个返回null 则后面的都不执行
    if (current == null) {
      return result;
    }
    result = current;
  }
  return result;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  throws BeansException {

  Object result = existingBean;
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
    Object current = processor.postProcessAfterInitialization(result, beanName);
    // 一个返回null 则后面的都不执行
    if (current == null) {
      return result;
    }
    result = current;
  }
  return result;
}

接下来还剩下一个重要的方法,那就是invokeInitMethods()方法,位于AbstractAutowireCapableBeanFactory类中,(从第1825行到第1857行),主要负责执行afterPropertiesSet()方法或则init-method方法完成Bean的初始化。给该Bean一个反应的机会,它的所有属性都已设置,并有机会了解它拥有的Bean 工厂(这个对象)。检查Bean是否实现了InitializingBean或定义了自定义的init-method方法,如果是,则调用必要的回调。其源码如下:

invokeAwareMethods()方法的两个参数:

  • @param :  beanName  Bean的名称

  • @param :  bean   需要初始化的Bean

  • @param :  mbd   合并Bean定义(也可以是null ,如果给定一个现有的Bean实例)

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
  throws Throwable {

  // 判断该Bean是否实现InitializingBean接口
  boolean isInitializingBean = (bean instanceof InitializingBean);
  // 这里init-method方法的名称不能是afterPropertiesSet
  // 并且这个类不是InitializingBean类型
  if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
    if (logger.isTraceEnabled()) {
      logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
    }
    if (System.getSecurityManager() != null) {
      try {
        AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
          // 调用InitializingBean的afterPropertiesSet()方法
          // 允许Bean实例在设置完所有的Bean属性后执行其整体配置和最终初始化的验证
          // 核心方法
          ((InitializingBean) bean).afterPropertiesSet();
          return null;
        }, getAccessControlContext());
      }
      catch (PrivilegedActionException pae) {
        throw pae.getException();
      }
    }
    else {
      ((InitializingBean) bean).afterPropertiesSet();
    }
  }

  if (mbd != null && bean.getClass() != NullBean.class) {
    // 获取init-method方法名称
    String initMethodName = mbd.getInitMethodName();
    // init-method方法的名称不能是afterPropertiesSet
    // 并且这个类不是InitializingBean类型
    if (StringUtils.hasLength(initMethodName) &&
        !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
        !mbd.isExternallyManagedInitMethod(initMethodName)) {
      // 调用指定的自定义init方法
      // 核心方法2
      invokeCustomInitMethod(beanName, bean, mbd);
    }
  }
}

 看一下invokeInitMethods()方法中的两个核心步骤:

// 调用InitializingBean的afterPropertiesSet()方法
// 在Bean的所有属性都设置完成后执行
// ---###--- STEP.EIGHTEEN : afterPropertiesSet ---###---
((InitializingBean) bean).afterPropertiesSet();
// 调用自定义的初始化方法 init-method
// ---###--- STEP.NINETEEN : invokeCustomInitMethod ---###---
invokeCustomInitMethod(beanName, bean, mbd);

需要注意的是,如果该Bean指定了init-method方法,那么这个Bean就不可以实现InitializingBean接口,并且init-method方法的名称还不可以是afterPropertiesSet,同时,自定义的init-method方法指定属性不能为空,且不能使用@PostConstruct注解标注(afterPropertiesSet()方法也不能使用该注解)。@PostConstruct先于InitializingBean.afterPropertiesSet()执行,InitializingBean.afterPropertiesSet()先于init-method的initMethod()。

在执行完invokeInitMethods()方法后,该Bean就完成了全部的初始化过程,接下来会去调用BeanPostProcessor后处理器的applyBeanPostProcessorsAfterInitialization方法,进行Bean初始化后的一些处理操作。

至此,AbstractApplicationContext.refresh()#finishBeanFactoryInitialization()方法全部执行完成,此时Bean已经完成了实例化和初始化,对于单例的Bean,在返回给用户的同时,会被添加到一级缓存中,也就是前面所说的singletonObjects;而对于原型的Bean,其剩余的生命周期会交由用户自己进行控制。

接下来就是销毁Bean,对于实现了DisposableBean接口的Bean,调用destroy()方法完成Bean的销毁,同时清理相关的缓存。具体源码如下,这里不在细说了。

public void destroy() throws Exception {
  Iterator var1 = this.injectedObjectsCache.values().iterator();

  while(var1.hasNext()) {
    Object object = var1.next();
    if (this.logger.isInfoEnabled()) {
      this.logger.info(object + " was destroying!");
    }

    if (object instanceof DisposableBean) {
      // 销毁Bean
      ((DisposableBean)object).destroy();
    }
  }

  this.injectionMetadataCache.clear();
  this.injectedObjectsCache.clear();
  if (this.logger.isInfoEnabled()) {
    this.logger.info(this.getClass() + " was destroying!");
  }

}

综上所述,Spring的IOC容器的启动流程如下图所示:

从Spring的IOC容器的启动执行到销毁的流程可以看出Bean的生命周期,总结如下:

46a34a04db25826ced17778c5d31d5b7.png

四、总结 

在做数据库迁移需求时,在设计接口切流方案时,需要对Spring的Bean生命周期有个较为清晰的了解,因此特意跟着源码学习了一下Bean的创建流程,虽然背八股的时候也了解过Bean的生命周期,但是所了解的也不够准确,本次通过源码,结合相关的参考文章,对Bean的生命周期有了个清楚的认识,还是有很多的收获的。

参考文章:

  1. Spring详解(四)----Spring IOC容器的设计与实现 - 唐浩荣 - 博客园
  2. 一文读懂 Spring Bean 的生命周期
  3. 基础精析|Spring BeanDefinition 与 IoC 容器启动过程 - 知乎
  4. 闲聊 InstantiationAwareBeanPostProcessor_星夜孤帆的博客-CSDN博客
  5. InstantiationAwareBeanPostProcessor解析_这瓜保熟么的博客-CSDN博客
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值