Spring中如何获取到一个Bean实例(一)?

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: Spring中如何获取到一个Bean实例(一)?

关联博文

关联博文

Spring后置处理器中的InstantiationAwareBeanPostProcessor详解

Spring中Bean实例化过程中的initializeBean方法

Spring中Bean实例化过程中的populateBean方法

Spring中@Autowired与@Resource自动注入实现原理


Spring中如何获取到一个Bean实例?

Spring中如何获取到一个Bean实例(二)?


其实这里想要说的是Spring容器中getBean的原理,也就是当你想从容器中获取到一个Bean时,Spring都做了什么?

如下所示,本文我们以常见的controller实例化过程为例进行分析。



AbstractBeanFactory#getBean(java.lang.String)
AbstractBeanFactory#doGetBean

【1】doGetBean


AbstractBeanFactory的doGetBean方法是获取到Bean实例的地方,但却不是创建、设置属性、解析依赖及后置处理的地方。这句话比较拗口,这个方法可以认为返回的是一个“处理”后的bean实例,但是其中一些环境比如设置属性、依赖解析是在更深层的的方法进行处理的。

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
    @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//处理bean名称,如去掉factoryBean的&前缀,解析别名
  final String beanName = transformedBeanName(name);
  Object bean;
  // Eagerly check singleton cache for manually registered singletons.
  // 急切检测单例bean是否正在创建或已经创建--这里涉及到三级缓存、依赖解决
  //尝试从一级、二级、三级缓存获取实例,
  //如果三级缓存获取到则放入二级缓存并从三级缓存移除
  Object sharedInstance = getSingleton(beanName);
  if (sharedInstance != null && args == null) {
    if (logger.isTraceEnabled()) {
      if (isSingletonCurrentlyInCreation(beanName)) {
        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 + "'");
      }
    }
    // 如果获取到的是工厂实例,那么尝试调用其getObject方法
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  }
  else {
    // Fail if we're already creating this bean instance:
    // We're assumably within a circular reference.
    // 如果当前bean是prototype且正在创建,则抛出异常
    if (isPrototypeCurrentlyInCreation(beanName)) {
      throw new BeanCurrentlyInCreationException(beanName);
    }
    // Check if bean definition exists in this factory.
    // 如果父容器不为空,且当前容器不包含该beanName则交给父容器处理
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
      // Not found -> check parent.
      String nameToLookup = originalBeanName(name);
      if (parentBeanFactory instanceof AbstractBeanFactory) {
        return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
            nameToLookup, requiredType, args, typeCheckOnly);
      }
      else if (args != null) {
        // Delegation to parent with explicit args.
        return (T) parentBeanFactory.getBean(nameToLookup, args);
      }
      else if (requiredType != null) {
        // No args -> delegate to standard getBean method.
        return parentBeanFactory.getBean(nameToLookup, requiredType);
      }
      else {
        return (T) parentBeanFactory.getBean(nameToLookup);
      }
    }
  // 标记当前bean已经被创建或者即将被创建
    if (!typeCheckOnly) {
      markBeanAsCreated(beanName);
    }
    try {
    // 获取到RootBeanDefinition,如果当前bean是child则与parent合并
      final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
      // 如果是abstract,则抛出BeanIsAbstractException
      checkMergedBeanDefinition(mbd, beanName, args);
      // Guarantee initialization of beans that the current bean depends on.
      //获取其物理依赖的bean
      String[] dependsOn = mbd.getDependsOn();
      if (dependsOn != null) {
        for (String dep : dependsOn) {
        // 如果二者相互依赖,抛出异常
          if (isDependent(beanName, dep)) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
          }
          //注册记录依赖关系
          registerDependentBean(dep, beanName);
          try {
          // 优先保证物理依赖的bean先初始化
            getBean(dep);
          }
          catch (NoSuchBeanDefinitionException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
          }
        }
      }
      // Create bean instance.
      // 单例bean的实例化
      if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, () -> {
          try {
            return createBean(beanName, mbd, args);
          }
          catch (BeansException ex) {
            // Explicitly remove instance from singleton cache: It might have been put there
            // eagerly by the creation process, to allow for circular reference resolution.
            // Also remove any beans that received a temporary reference to the bean.
            destroySingleton(beanName);
            throw ex;
          }
        });
        // 如果获取到的是工厂实例,那么尝试调用其getObject方法
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
      }
// 多态/原型bean的实例化
      else if (mbd.isPrototype()) {
        // It's a prototype -> create a new instance.
        Object prototypeInstance = null;
        try {
          beforePrototypeCreation(beanName);
          prototypeInstance = createBean(beanName, mbd, args);
        }
        finally {
          afterPrototypeCreation(beanName);
        }
        // 如果获取到的是工厂实例,那么尝试调用其getObject方法
        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
      }
// 其他scope比如request bean的实例化
      else {
        String scopeName = mbd.getScope();
        final 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);
            }
          });
          // 如果获取到的是工厂实例,那么尝试调用其getObject方法
          bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
        }
        catch (IllegalStateException ex) {
          throw new BeanCreationException(beanName,
              "Scope '" + scopeName + "' is not active for the current thread; consider " +
              "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
              ex);
        }
      }
    }
    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)) {
    try {
    // 进行类型转换
      T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
      if (convertedBean == null) {
        throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
      }
      return convertedBean;
    }
    catch (TypeMismatchException ex) {
      if (logger.isTraceEnabled()) {
        logger.trace("Failed to convert bean '" + name + "' to required type '" +
            ClassUtils.getQualifiedName(requiredType) + "'", ex);
      }
      throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    }
  }
  // 返回得到的bean
  return (T) bean;
}


代码逻辑梳理如下流程:


① 处理bean名称,如去掉factoryBean的&前缀,解析别名

② 急切检测单例bean是否正在创建或已经创建–这里涉及到三级缓存、循环依赖

③ 如果父容器不为空,且当前容器不包含该beanName则交给父容器处理

④ 获取到RootBeanDefinition,如果当前bean是child则与parent合并

⑤ 获取其物理依赖的bean-dependsOn 哦,进行处理。

⑥ 单例bean的实例化、prototype bean实例化、其他scope bean实例化

⑦ 尝试进行bean的类型转换,如果需要的话

⑧ 返回获取到的bean。

关于三级缓存(循环依赖)可以参考博文:Spring中的循环依赖详解 。

dependsOn

这个其实是指@DependsOn注解,如果是以前xml配置则是如下格式:

<bean dependens on=“…”/>


@DependsOn注解主要用于指定当前bean所依赖的beans。任何被指定依赖的bean都由Spring保证在当前bean之前创建。在少数情况下,bean不是通过属性或构造函数参数显式依赖于另一个bean,但却需要要求另一个bean优先完成初始化,则可以使用@DependsOn这个注解。


@DependsOn既可以指定初始化依赖顺序,也可以指定bean相应的销毁执行顺序(仅在单例bean的情况下,只有单例beanSpring才会管理器生命周期)。


可用于任何直接或间接带@Component注解的bean或在用@Bean注释的方法上。这里的“依赖”是物理上的,区别与我们@Autowired业务上的“依赖注入”,一定要分清哦。

我们暂以单例bean的获取来分析实例化过程,也就是如下代码。

if (mbd.isSingleton()) {
  sharedInstance = getSingleton(beanName, () -> {
    try {
      return createBean(beanName, mbd, args);
    }
    catch (BeansException ex) {
      destroySingleton(beanName);
      throw ex;
    }
  });
  bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}


如下所示ObjectFactory是一个功能性接口,其可以使用匿名函数与λ表达式。

@FunctionalInterface
public interface ObjectFactory<T> {
  T getObject() throws BeansException;
}
// 匿名函数
() -> {
  try {
    return createBean(beanName, mbd, args);
  }
  catch (BeansException ex) {
    destroySingleton(beanName);
    throw ex;
  }
}


接下来我们分析getSingleton、createBean以及getObjectForBeanInstance方法。

【2】单例bean的获取

① getSingleton方法

这里是DefaultSingletonBeanRegistry的getSingleton方法。该方法是尝试查找已经注册的bean,如果还没有注册则创建并注册bean实例。

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);
    // 如果一级缓存获取不到该bean
    if (singletonObject == null) {
       // 如果正在销毁,则抛出异常
      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!)");
      }
      //...
      }
  // 创建bean的前置方法,其实就是放到singletonsCurrentlyInCreation中
  // 这里可能会抛出BeanCurrentlyInCreationException
      beforeSingletonCreation(beanName);
      // 是否新创建备案
      boolean newSingleton = false;
      // 是否记录异常
      boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
      if (recordSuppressedExceptions) {
        this.suppressedExceptions = new LinkedHashSet<>();
      }
      try {
      // 核心方法,使用工厂的getObject方法获取bean
      // 这里会触发createBean
        singletonObject = singletonFactory.getObject();
        newSingleton = true;
      }
      catch (IllegalStateException ex) {
        // Has the singleton object implicitly appeared in the meantime ->
        // if yes, proceed with it since the exception indicates that state.
        // 如果创建的过程抛出了异常,则再次从一级缓存里面获取
        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;
        }
        // 从singletonsCurrentlyInCreation移除
        afterSingletonCreation(beanName);
      }
      // 如果是新创建的单例bean,放入singletonObjects、registeredSingletons
      // 从二级缓存earlySingletonObjects、三级缓存singletonFactories移除
      if (newSingleton) {
        addSingleton(beanName, singletonObject);
      }
    }
    return singletonObject;
  }
}



方法逻辑如上代码所示,首先从一级缓存里面尝试获取bean,如果获取不到则将beanName放到singletonsCurrentlyInCreation然后触发createBean进行bean的创建,并从singletonsCurrentlyInCreation移除。最后将新创建的单例bean,放入singletonObjects、registeredSingletons并从二级缓存earlySingletonObjects、三级缓存singletonFactories移除。


关于三级缓存本文不再分析,下面我们着重看下singletonFactory.getObject();也就是createBean(beanName, mbd, args);。

② createBean

这里指的是AbstractAutowireCapableBeanFactory的createBean方法。

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
//...
  RootBeanDefinition mbdToUse = mbd;
// 获取bean class 与 RootBeanDefinition(in case of a dynamically resolved Class)
  Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    mbdToUse = new RootBeanDefinition(mbd);
    mbdToUse.setBeanClass(resolvedClass);
  }
  // Prepare method overrides.
  try {
    mbdToUse.prepareMethodOverrides();
  }
  catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
        beanName, "Validation of method overrides failed", ex);
  }
  try {
    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    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 {
  // 创建Bean的核心入口
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    //... 省略了日志打印
    return beanInstance;
  }
  catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
    throw ex;
  }
  catch (Throwable ex) {
    throw new BeanCreationException(
        mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  }
}

可以看到这里首先获取RootBeanDefinition与Bean class,然后调用doCreateBean方法完成bean的实例化。这里需要注意的是resolveBeforeInstantiation方法。


如下所示这里会首先尝试调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,如果得到的bean不为null,那么尝试调用BeanPostProcessor 的postProcessAfterInitialization方法。特别需要注意的是,如果这里返回的bean不为null,那么不会再执行下游的doCreateBean方法,将会直接返回。相当于bean实例流程的短路。

// AbstractAutowireCapableBeanFactory
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  Object bean = null;
  if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    // Make sure bean class is actually resolved at this point.
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      Class<?> targetType = determineTargetType(beanName, mbd);
      if (targetType != null) {
        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
        if (bean != null) {
          bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
        }
      }
    }
    mbd.beforeInstantiationResolved = (bean != null);
  }
  return bean;
}
// AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
  for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
      InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
      Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
      if (result != null) {
        return result;
      }
    }
  }
  return null;
}
// AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {
  Object result = existingBean;
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
    Object current = processor.postProcessAfterInitialization(result, beanName);
    if (current == null) {
      return result;
    }
    result = current;
  }
  return result;
}

关于InstantiationAwareBeanPostProcessor 的postProcessBeforeInstantiation方法,大部分都默认返回null,但是需要注意的是AbstractAutoProxyCreator,其postProcessBeforeInstantiation方法会尝试为bean创建代理,如果当前bean有自定义CustomTargetSource的话。


关于BeanPostProcessor 的postProcessAfterInitialization默认情况下是返回bean,但是比如AbstractAutoProxyCreator的postProcessAfterInitialization方法将会尝试为bean进行包装返回代理–这里也是AOP为bean产生代理的核心方法。关于这个可以参考博文Spring AOP如何为目标方法创建拦截器链?。


我们继续回去跟踪Object beanInstance = doCreateBean(beanName, mbdToUse, args);方法。

③ doCreateBean

这里是AbstractAutowireCapableBeanFactoryd的doCreateBean方法。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
  // Instantiate the bean.
  BeanWrapper instanceWrapper = null;
  if (mbd.isSingleton()) {
  // 如果是单例且是工厂bean,从工厂bean缓存中移除,并把value赋予instanceWrapper 
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  }
  if (instanceWrapper == null) {
  // 如果instanceWrapper 为null,则进行初始化,这里是基础的初始化bean
    instanceWrapper = createBeanInstance(beanName, mbd, args);
  }
  // 获取bean实例与class 类型
  final Object bean = instanceWrapper.getWrappedInstance();
  Class<?> beanType = instanceWrapper.getWrappedClass();
  if (beanType != NullBean.class) {
    mbd.resolvedTargetType = beanType;
  }
  // Allow post-processors to modify the merged bean definition.
  synchronized (mbd.postProcessingLock) {
    if (!mbd.postProcessed) {
      try {
// 给MergedBeanDefinitionPostProcessor一个机会postProcessMergedBeanDefinition
        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      }
      catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
            "Post-processing of merged bean definition failed", ex);
      }
      //标记mbd经过了后置处理
      mbd.postProcessed = true;
    }
  }
  // Eagerly cache singletons to be able to resolve circular references
  // even when triggered by lifecycle interfaces like BeanFactoryAware.
  //单例&允许循环引用&正在实例化 -- 允许早期暴露
  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");
    }
// 如果singletonObjects不包含beanName,放入singletonFactories/registeredSingletons
// 从二级缓存earlySingletonObjects移除
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  }
  // Initialize the bean instance.
  Object exposedObject = bean;
  try {
  // 解析依赖注入、属性赋值
    populateBean(beanName, mbd, instanceWrapper);
    // 实例化后置处理
    exposedObject = initializeBean(beanName, exposedObject, mbd);
  }
  catch (Throwable ex) {
  // 抛出异常BeanCreationException 
  //...
  }
  if (earlySingletonExposure) {
  // 从一级缓存或者二级缓存得到bean实例的引用
    Object earlySingletonReference = getSingleton(beanName, false);
    if (earlySingletonReference != null) {
      if (exposedObject == bean) {
      //如果指向同一个bean,把exposedObject 指向earlySingletonReference
        exposedObject = earlySingletonReference;
      }
      else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
      // 如果当前bean有其他bean物理依赖-dependensOn,进行处理
        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 " +
              "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
        }
      }
    }
  }
  // Register bean as disposable.
  try {
  // 如果当前bean非Prototype,尝试注册DisposableBean,放到disposableBeans中
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
  }
  catch (BeanDefinitionValidationException ex) {
    throw new BeanCreationException(
        mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  }
  return exposedObject;
}

方法逻辑梳理如下:


① 实例化bean,得到bean实例与class 类型,这时是基础实例化;

② 给MergedBeanDefinitionPostProcessor一个机会触发postProcessMergedBeanDefinition

③ addSingletonFactory,关于三级缓存的处理,这里如果singletonObjects不包含beanName,放入singletonFactories/registeredSingletons,从二级缓存earlySingletonObjects移除;

④ populateBean进行依赖解析、属性赋值

⑤ initializeBean进行bean实例化的后半部分;

⑥ earlySingletonExposure为true时进行单例bean的并发实例、物理依赖的处理

⑦ 如果当前bean非Prototype,尝试注册DisposableBean,放到disposableBeans中

⑧ 返回exposedObject。

关于populateBean与initializeBean方法这里不再赘述,可以参考博文Spring中Bean实例化过程中的initializeBean方法,Spring中Bean实例化过程中的populateBean方法。

addSingletonFactory

我们先看一下addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));方法。这里其实是对三级缓存的处理,如果一级缓存singletonObjects不包含beanName时,则放入三级缓存(value为ObjectFactory),并从二级缓存移除。

//DefaultSingletonBeanRegistry#addSingletonFactory
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
  Assert.notNull(singletonFactory, "Singleton factory must not be null");
  synchronized (this.singletonObjects) {
  // 如果一级缓存里面不包含beanName
    if (!this.singletonObjects.containsKey(beanName)) {
    // 放入三级缓存
      this.singletonFactories.put(beanName, singletonFactory);
      //从二级缓存移除
      this.earlySingletonObjects.remove(beanName);
      // 放入registeredSingletons
      this.registeredSingletons.add(beanName);
    }
  }
}
// AbstractAutowireCapableBeanFactory#getEarlyBeanReference
// 获取早期引用
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
  Object exposedObject = bean;
  if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
        SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
        exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
      }
    }
  }
  return exposedObject;
}


可以看到其调用了SmartInstantiationAwareBeanPostProcessor 的getEarlyBeanReference方法。这里其实要注意的是AbstractAutoProxyCreator,如下所示其首先为当前bean创建缓存key然后放到earlyProxyReferences中,最后判断其是否需要创建代理。


@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
  Object cacheKey = getCacheKey(bean.getClass(), beanName);
  this.earlyProxyReferences.put(cacheKey, bean);
  return wrapIfNecessary(bean, beanName, cacheKey);
}


createBeanInstance

最后我们再看下createBeanInstance(beanName, mbd, args);方法。这里会进行bean的初步实例化,其将会采取比如工厂方法、构造器注入或者其他实例化策略。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
  // Make sure bean class is actually resolved at this point.
  Class<?> beanClass = resolveBeanClass(mbd, beanName);
//判断修饰符是否为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());
  }
  Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
  if (instanceSupplier != null) {
    return obtainFromSupplier(instanceSupplier, beanName);
  }
// 如果有工厂方法,则使用工厂方法实例化
  if (mbd.getFactoryMethodName() != null) {
    return instantiateUsingFactoryMethod(beanName, mbd, args);
  }
  // Shortcut when re-creating the same bean...
  boolean resolved = false;
  boolean autowireNecessary = false;
  if (args == null) {//args默认为null
    synchronized (mbd.constructorArgumentLock) {
      if (mbd.resolvedConstructorOrFactoryMethod != null) {
        resolved = true;
        // 默认为false,autowireConstructor会将其变为true
        autowireNecessary = mbd.constructorArgumentsResolved;
      }
    }
  }
//如果resolvedConstructorOrFactoryMethod 不为null,也就是说曾经加载/解析过当前bean定义,
//resolvedConstructorOrFactoryMethod 值可能是构造函数或者工厂方法
  if (resolved) {
    if (autowireNecessary) {
    // 针对@Autowired构造函数注入
      return autowireConstructor(beanName, mbd, null, null);
    }
    else {
    // 默认实例化
      return instantiateBean(beanName, mbd);
    }
  }
  // Candidate constructors for autowiring?
  // 选择一个候选构造器函数
  Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
      mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
    return autowireConstructor(beanName, mbd, ctors, args);
  }
  // Preferred constructors for default construction?
  //默认为null
  ctors = mbd.getPreferredConstructors();
  if (ctors != null) {
    return autowireConstructor(beanName, mbd, ctors, null);
  }
  // No special handling: simply use no-arg constructor.
  //比如我们的fileController就通过这里进行了实例化
  return instantiateBean(beanName, mbd);
}


这里determineConstructorsFromBeanPostProcessors其实主要指的是AutowiredAnnotationBeanPostProcessor,其他SmartInstantiationAwareBeanPostProcessor默认情况下返回的是null。


AutowiredAnnotationBeanPostProcessor选择构造器的逻辑是:


遍历所有的构造方法,如果有Autowired(required=true)的构造函数且只有一个返回该构造函数

遍历所有的构造方法,如果有Autowired(required=true)的构造函数且有多个,报错

如果有多个注解标注的构造函数,则返回所有注解标注的外加无参构造

如果只有一个构造函数返回该构造函数

其他情况返回nullautowireConstructor的逻辑是:



将所有的候选构造函数排序,排序规则[第一排序规则: public方法优先,第二排序规则:参数数量降序]

设置一个算法,输入构造函数,输出一个整数

判断构造方法能否完成依赖注入,不能跳过该构造函数

算法输出的最小值则作为被选中的构造函数

通过选中的构造函数完成对象实例化

算法根据mbd.isLenientConstructorResolution(默认宽松模式)区分严格模式和宽松模式,不同的模式有不同计算方式

关于构造器选择与实例化可参考博文determineCandidateConstructors与autowireConstructor


到这里为止,我们的fileController就初步进行了实例化,之后我们看一下getObjectForBeanInstance方法。

④ getObjectForBeanInstance

我们分别看下AbstractAutowireCapableBeanFactory与父类AbstractBeanFactoryd的getObjectForBeanInstance方法。

//AbstractAutowireCapableBeanFactory#getObjectForBeanInstance
// 通常 name与beanName是一致的
protected Object getObjectForBeanInstance(
    Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
  // 大部分情况下,这里为null
  String currentlyCreatedBean = this.currentlyCreatedBean.get();
  // 如果currentlyCreatedBean不为null,则注册依赖关系
  if (currentlyCreatedBean != null) {
    registerDependentBean(beanName, currentlyCreatedBean);
  }
//调用父类AbstractBeanFactory#getObjectForBeanInstance
  return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}


父类AbstractBeanFactory的getObjectForBeanInstance方法如下所示,方法核心即:


如果beanName以& 开头,要么返回NullBean,要么返回工厂bean自身;

如果非FactoryBean则直接返回

从factoryBeanObjectCache缓存中获取结果对象

触发工厂bean的getObject获取结果对象

protected Object getObjectForBeanInstance(
    Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
  // Don't let calling code try to dereference the factory if the bean isn't a factory.
  // 如果beanName以& 开头
  if (BeanFactoryUtils.isFactoryDereference(name)) {
    if (beanInstance instanceof NullBean) {
      return beanInstance;
    }
    if (!(beanInstance instanceof FactoryBean)) {
      throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
    }
    if (mbd != null) {
      mbd.isFactoryBean = true;
    }
    // 意思是获取工厂bean本身
    return beanInstance;
  }
  // Now we have the bean instance, which may be a normal bean or a FactoryBean.
  // If it's a FactoryBean, we use it to create a bean instance, unless the
  // caller actually wants a reference to the factory.
  // 如果不是工厂bean,直接返回。
  if (!(beanInstance instanceof FactoryBean)) {
    return beanInstance;
  }
  Object object = null;
  if (mbd != null) {
    mbd.isFactoryBean = true;
  }
  else {
  // 从factoryBeanObjectCache缓存中获取object
    object = getCachedObjectForFactoryBean(beanName);
  }
  // 如果没有获取过,即不能从缓存里面拿到,则触发getObject方法获取结果
  if (object == null) {
    // Return bean instance from factory.
    FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
    // Caches object obtained from FactoryBean if it is a singleton.
    if (mbd == null && containsBeanDefinition(beanName)) {
      mbd = getMergedLocalBeanDefinition(beanName);
    }
    boolean synthetic = (mbd != null && mbd.isSynthetic());
    object = getObjectFromFactoryBean(factory, beanName, !synthetic);
  }
  return object;
}


至此,我们就分析完单例bean的实例化过程,至于其他scope的可参考分析。

目录
相关文章
|
6天前
|
XML Java 数据格式
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
14 1
|
6天前
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
9 0
|
7天前
|
Java Spring
Spring的BeanPostProcessor后置处理器与bean的生命周期
Spring的BeanPostProcessor后置处理器与bean的生命周期
|
8天前
|
Java Spring 容器
解读spring5源码中实例化单例bean的调用链
解读spring5源码中实例化单例bean的调用链
|
10天前
|
运维 Java 关系型数据库
Spring运维之boot项目bean属性的绑定读取与校验
Spring运维之boot项目bean属性的绑定读取与校验
16 2
|
7天前
|
Java Spring
Spring注解内容----用来替代Bean
Spring注解内容----用来替代Bean
|
7天前
|
Java Linux 程序员
技术笔记:Spring生态研习【五】:Springboot中bean的条件注入
技术笔记:Spring生态研习【五】:Springboot中bean的条件注入
|
8天前
|
Java Spring
聊聊Spring中两种创建Bean的方式:BeanDefinition.setInstanceSupplier() 和 FactoryBean
聊聊Spring中两种创建Bean的方式:BeanDefinition.setInstanceSupplier() 和 FactoryBean
|
8天前
|
Java 开发者 Spring
Spring的Bean的生命周期各个阶段扩展方法
Spring的Bean的生命周期各个阶段扩展方法
|
13天前
|
Java Maven Spring
Spring中AOP最简单实例-@注解形式
Spring中AOP最简单实例-@注解形式
20 0