spring bean加载过程_10年架构师深入解析:Spring源码阅读之初始化"非懒加载bean"实例...

前言

在经历了前面BeanDefinition定义和BeanPostProcessor的准备工作完成之后,终于到了千呼万唤始出来的bean实例初始化了,也就是平时想用哪个类对应的实例直接从BeanFactory要的对象时怎么被创建出来的?由于这块逻辑比较复杂,还涉及到"循环依赖"等等一系列问题,所以我会在接下来利用两三篇文章来逐一说明。你们准备好一次搞定bean实例初始化的流程了吗?关于测试用例我们还是沿用UserService。

(本文来自公众号:z小赵)

bcd4d36a2a1d572629af0fef71652cde.png

说明一下,关于以下几个方法,不是我们关注的重点,暂时先不讨论,后面有时间我们再来介绍

  • initMessageSource():初始化国际化相关
  • initApplicationEventMulticaster():初始化事件分发器
  • onRefresh():初始化特殊的bean实例,无任何实现,预留出来的扩展点
  • registerListeners():注册监听器

  1. 关于BeanDefinition的几点提前说明
  • GenericBeanDefinition:配置为xml文件被解析为这个BeanDefinition定义
  • ScannedGenericBeanDefinition:由注解声明的被解析成这个BeanDefinition
  • 在bean实例化开始我们会遇到一个叫mergedBeanDefinition的bean定义,由于BeanDefinition会存在如下情况:
  • BeanDefinition存在父BeanDefinition
  • BeanDefinition不存在父BeanDefinition且本身是一个RootBeanDefinition
  • BeanDefinition不是一个RootBeanDefinition,而是一个自定义的BeanDefinition

所以在bean实例化开始把这些情况统一命名为mergedBeanDefinition。


  1. 看看finishBeanFactoryInitialization()的具体实现。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {      // Initialize conversion service for this context.      // Step1:初始化当前上下文的转换器      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));      }      // Register a default embedded value resolver if no bean post-processor      // (such as a PropertyPlaceholderConfigurer bean) registered any before:      // at this point, primarily for resolution in annotation attribute values.      // Step2:如果BeanFactory没有内嵌值解析器,则添加一个默认的值解析器,这个解析器的作用是将注解里面配的类似 ${} 替换成真正的值      if (!beanFactory.hasEmbeddedValueResolver()) {          beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));      }      // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.      // Step3:初始化LoadTimeWeaverAware bean实例      String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);      for (String weaverAwareName : weaverAwareNames) {          getBean(weaverAwareName);      }      // Stop using the temporary ClassLoader for type matching.      beanFactory.setTempClassLoader(null);      // Allow for caching all bean definition metadata, not expecting further changes.      // Step4:冻结BeanDefinition定义,因为之后就是开始创建BeanDefinition对应的实例了      beanFactory.freezeConfiguration();      // Instantiate all remaining (non-lazy-init) singletons.      // Step5:重点,实例化所有剩余的非懒加载的单例Bean实例      beanFactory.preInstantiateSingletons();}

  1. 来看下beanFactory.preInstantiateSingletons()的具体实现。
public void preInstantiateSingletons() throws BeansException {      if (this.logger.isDebugEnabled()) {          this.logger.debug("Pre-instantiating singletons in " + this);      }      // Iterate over a copy to allow for init methods which in turn register new bean definitions.      // While this may not be part of the regular factory bootstrap, it does otherwise work fine.      List beanNames = new ArrayList<>(this.beanDefinitionNames);      // Trigger initialization of all non-lazy singleton beans...      // Step1:遍历当前BeanFactory里面的所有beanName      for (String beanName : beanNames) {          // Step1.1:根据beanName获取对应的MergedBeanDefinition定义。          RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);          // Step1.2:bd不是抽象的 && bd是单例的 && bd是非懒加载的          if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {              // Step1.2.1:根据当前beanName判断对应的bean实例是否是一个FactoryBean。              if (isFactoryBean(beanName)) {                  // Step1.2.1.1:带上前缀获取FactoryBean                  Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);                  // Step1.2.1.2:获取到的bean是一个FactoryBean                  if (bean instanceof FactoryBean) {                      final FactoryBean> factory = (FactoryBean>) bean;                      boolean isEagerInit;                      if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {                          isEagerInit = AccessController.doPrivileged((PrivilegedAction)                                          ((SmartFactoryBean>) factory)::isEagerInit,                                  getAccessControlContext());                      }                      else {                          isEagerInit = (factory instanceof SmartFactoryBean &&                                  ((SmartFactoryBean>) factory).isEagerInit());                      }                      // Step1.2.1.3:需要提前加载,根据beanName获取对应的bean实例并将其注册到BeanFactory里面。                      if (isEagerInit) {                          getBean(beanName);                      }                  }              }              //1.2.2:非FactoryBean,则直接获取对应的bean实例并将其注册到BeanFactory里面。              else {                  getBean(beanName);              }          }      }      // Trigger post-initialization callback for all applicable beans...      // Step2:遍历beanName获取对应的bean实例。      for (String beanName : beanNames) {          Object singletonInstance = getSingleton(beanName);          // Step2.1:如果当前实例实现了SmartInitializingSingleton,则可以调用其实现的afterSingletonsInstantiated方法,可以在这个方法中做一些事情。          if (singletonInstance instanceof SmartInitializingSingleton) {              final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;              // Step2.1.1:是否需要安全检测              if (System.getSecurityManager() != null) {                  AccessController.doPrivileged((PrivilegedAction) () -> {                      smartSingleton.afterSingletonsInstantiated();                      return null;                  }, getAccessControlContext());              }              else {                  smartSingleton.afterSingletonsInstantiated();              }          }      }}

  1. 基于以上的实现,我们先来看看如果根据beanName获取到对应的MergedBeanDefinition定义的。
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {      // Quick check on the concurrent map first, with minimal locking.      // Step1:存MergedBeanDefinitions缓存获取对应的BeanDefinition定义,快速返回BeanDefinition定义,这种类似的缓存在Sprin后面的源码也会大量用到,我们在文末总结一下今天见到的本地缓存      RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);      if (mbd != null) {          return mbd;      }      // Step2:首先根据beanName获取到对应的BeanDefinition定义,然后在根据BeanDefinition和beanName获取到RootBeanDefinition。      return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));}
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {      // Step1:从beanDefinitionMap获取对应的BeanDefinition,这里存放的就是我们在 obtainFreshBeanFactory() 方法里面创建出来的BeanDefinition定义,理论上这里肯定可以获取得到对应的BeanDefinition,如果取不到就抛出异常。      BeanDefinition bd = this.beanDefinitionMap.get(beanName);            if (bd == null) {          if (this.logger.isTraceEnabled()) {              this.logger.trace("No bean named '" + beanName + "' found in " + this);          }          throw new NoSuchBeanDefinitionException(beanName);      }      return bd;}

  1. 根据beanName和BeanDefinition获取对应的RootBeanDefinition定义
// 拿到了beanName和对应的BeanDefinition定义,我们来看看是怎么获取到对应的RootBeanDefinition定义的。protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {    synchronized (this.mergedBeanDefinitions) {        RootBeanDefinition mbd = null;        // Check with full lock now in order to enforce the same merged instance.        // Step1:从缓存中获取对应的RootBeanDefinition定义。        if (containingBd == null) {            mbd = this.mergedBeanDefinitions.get(beanName);        }        // Step2:本地缓存中不存在。        if (mbd == null) {            // Step2.1:判断当前BeanDefinition是否存在父BeanDefinition,如果不存在父BeanDefinition。            if (bd.getParentName() == null) {                // Use copy of given root bean definition.                // Step2.1.1:实现了RootBeanDefinition接口,则拿BeanDefinition克隆一个RootBeanDefinition                if (bd instanceof RootBeanDefinition) {                    mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();                }                else {                    // Step2.1.2:直接使用当前BeanDefinition创建一个对应的RootBeanDefinition定义。                    mbd = new RootBeanDefinition(bd);                }            }            else {                // Child bean definition: needs to be merged with parent.                // Step2.2:存在父BeanDefinition,获取父BeanDefinition对应的名字                BeanDefinition pbd;                try {                    String parentBeanName = transformedBeanName(bd.getParentName());                    // Step2.3:判断当前BeanName和父BeanName不同,则根据父beanName获取父BeanDefinition定义                    if (!beanName.equals(parentBeanName)) {                        pbd = getMergedBeanDefinition(parentBeanName);                    }                    else {                        // Step2.4:获取父BeanFactory,如果父BeanFactory实现了ConfigurableBeanFactory接口,使用父BeanFactory获取父BeanDefinition                        BeanFactory parent = getParentBeanFactory();                        if (parent instanceof ConfigurableBeanFactory) {                            pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);                        }                        else {                            throw new NoSuchBeanDefinitionException(parentBeanName,                                    "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +                                    "': cannot be resolved without an AbstractBeanFactory parent");                        }                    }                }                catch (NoSuchBeanDefinitionException ex) {                    throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,                            "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);                }                // Deep copy with overridden values.                // Step2.3:使用父BeanDefinition创建一个RootBeanDefinition定义,然后将当前BeanDefinition(子BeanDefinition)的属性覆盖上去。                mbd = new RootBeanDefinition(pbd);                mbd.overrideFrom(bd);            }            // Set default singleton scope, if not configured before.            // Step2.4:设置scope属性,默认的都是单例的。            if (!StringUtils.hasLength(mbd.getScope())) {                mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);            }            // A bean contained in a non-singleton bean cannot be a singleton itself.            // Let's correct this on the fly here, since this might be the result of            // parent-child merging for the outer bean, in which case the original inner bean            // definition will not have inherited the merged outer bean's singleton status.            // Step2.5:对外部传进来的BeanDefinition设置scope属性。            if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {                mbd.setScope(containingBd.getScope());            }            // Cache the merged bean definition for the time being            // (it might still get re-merged later on in order to pick up metadata changes)            // Step2.6:将创建出来的RootBeanDefinition定义回种到本地缓存里面。            if (containingBd == null && isCacheBeanMetadata()) {                this.mergedBeanDefinitions.put(beanName, mbd);            }        }        // Step3:返回创建好的RootBeanDefinition定义。        return mbd;    }}

  1. 获取当前BeanDefinition对应的父BeanDefinition对应的beanName。
// 接着看看根据父beanName获取对应的名字protected String transformedBeanName(String name) {    // BeanFactoryUtils.transformedBeanName这个操作就是将FactoryBean的前缀去掉。    return canonicalName(BeanFactoryUtils.transformedBeanName(name));}public String canonicalName(String name) {    String canonicalName = name;    // Handle aliasing...    String resolvedName;    do {        // 从别名map里面获取对应的beanName,返回别名对应的真实beanName。        resolvedName = this.aliasMap.get(canonicalName);        if (resolvedName != null) {            canonicalName = resolvedName;        }    }    while (resolvedName != null);    return canonicalName;}

  1. 拿到了父beanName,根据父beanName获取对应的BeanDefinition定义。
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {      // Step1. 获取别名对应的真实beanName。    String beanName = transformedBeanName(name);    // Efficiently check whether bean definition exists in this factory.    // Step2:如果当前的BeanFactory不存在BeanDefinition定义 && 父BeanFactory实现了ConfigurableBeanFactory,则从父BeanFactory里面获取对应的RootBeanDefinition定义。    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {        return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);    }    // Resolve merged bean definition locally.    // Step3:没取到,则新创建。    return getMergedLocalBeanDefinition(beanName);}protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {      // Quick check on the concurrent map first, with minimal locking.      // Step1:从mergedBeanDefinitions缓存优先获取,取到则直接返回。      RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);      if (mbd != null) {          return mbd;      }      // Step2:如果没有取到,则根据当前的beanName获取对应的beanDefinition定义,然后在递归调用getMergedBeanDefinition()方法获取对应的RootBeanDefinition定义。      return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));}

  1. 以上内容稍微绕点,仔细看两遍应该也比较好懂,总结一下就是如果当前BeanDefinition存在父BeanDefinition,则先获取到父BeanDefinition,然后在将当前BeanDefinition的属性覆盖到父BeanDefinition上,然后创建对应的RootBeanDefinition返回。到此我们得到了RootBeanDefinition定义,接下来看看beanName对应的实例是否是FactoryBean。
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {      // Step1:获取真实的beanName      String beanName = transformedBeanName(name);      // Step2:获取beanName对应的bean实例      Object beanInstance = getSingleton(beanName, false);      // Step3:如果获取到了对应的bean实例,则直接判断其是否实现了FactoryBean接口,如果是则认为是FactoryBean。      if (beanInstance != null) {          return (beanInstance instanceof FactoryBean);      }      // No singleton instance found -> check bean definition.      // Step4:如果当前BeanFactory里面不存在对应的bean实例,则从父BeanFactory里面获取。      if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {          // No bean definition found in this factory -> delegate to parent.          return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);      }      // Step5:当前BeanFactory存在,则选获取对应RootBeanDefinition定义,获取对应的beanType,根据beanType判断是否是一个FactoryBean。      return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));}

  1. 接着来看看getSingleton()是怎么获取beanName对应的bean实例的。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {      // Step1:从singletonObjects缓存中获取对象      Object singletonObject = this.singletonObjects.get(beanName);      // Step2:如果从缓存中没取到 && beanName对应的bean实例正在创建中      if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {          synchronized (this.singletonObjects) {              // Step2.1:从earlySingletonObjects缓存中获取对应的bean实例              singletonObject = this.earlySingletonObjects.get(beanName);              // Step2.2:从缓存中没有取到 && allowEarlyReference为true              if (singletonObject == null && allowEarlyReference) {                  // Step2.2.1:从singletonFactories缓存中获取bean实例,如果能获取到,将bean实例回种到前两个缓存中,然后将bean实例返回。                  ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);                  if (singletonFactory != null) {                      singletonObject = singletonFactory.getObject();                      this.earlySingletonObjects.put(beanName, singletonObject);                      this.singletonFactories.remove(beanName);                  }              }          }      }      // Step3:返回bean实例      return singletonObject;}

  1. 再来看看isFactoryBean()是怎么预测beanType是否是FactoryBean的。
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {      // Step1:根据beanName和RootBeanDefinition获取一个bean类型。      Class> beanType = predictBeanType(beanName, mbd, FactoryBean.class);      // Step2:如果有对应的bean类型 && 如果bean类型是通过FactoryBean分配的,则认为是一个FactoryBean。isAssignableFrom调用的是一个native方法。      return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));}

总结

来总结一下本篇文章里面遇到的几个本地缓存。

  • beanDefinitionMap:存放BeanDefinition定义
  • mergedBeanDefinitions:存放RootBeanDefinition定义
  • singletonObjects:存放bean实例,相当于bean实例的一级缓存
  • earlySingletonObjects:存放bean实例,相当于bean实例的二级缓存
  • singletonFactories:存放bean实例对应的BeanFactory,通过BeanFactory创建相应的bean实例,相当于bean实例的三级缓存
  • singletonsCurrentlyInCreation:存放当前正在创建的bean实例

到此,我们遍历了每个beanName拿到了对应的RootBeanDefinition定义,然后判断了beanName对应的bean实例是否是一个FactoryBean。下一篇文章来分析根据beanName获取对应的bean实例。


d8b3f98b31355e47696c530187b7bcb7.png

上一篇我们分析了创建bean实例需要的RootBeanDefinition定义的构建。今天我们在接着继续讨论,拿到RootBeanDefinition定义后,如何创建bean实例。但在创建bean实例前还有个很重要的知识点需要提前讲解一下什么是FactoryBean,因为在创建bean实例的时候很多地方会遇到。

目前Spring创建bean实例都是通过配置指定的class属性,利用反射的方式来创建的,但是在某些情况下,通过配置的方式创建bean实例并不灵活,所以Spring提供了另外一种方式来创建bean实例,就是通过实现FactoryBean接口,重写其方法,通过调用getObject()方法来获取bean实例,Spring本身也大量使用这种方式来创建bean实例。接下来我们来具体看下如果使用FactoryBean创建一个bean实例出来。

  1. 实现FactoryBean接口,重写其方法,源码如下。
package Service;import org.springframework.beans.factory.FactoryBean;import model.Car;/** * @author zxz * 实现FactoryBean接口,重写其方法 */public class CarFactoryBean implements FactoryBean {    /**     * 返回实际的bean实例,该方法会在getBean的时候通过CarFactoryBean对象调用     *     * @return     * @throws Exception     */    public Car getObject() throws Exception {        return new Car("audi", 300000);    }    /**     * 返回实际的bean对应的class类型     *     * @return     */    public Class> getObjectType() {        return Car.class;    }    /**     * 返回bean实例是否是单例,true:表示目标实例是单例的,会被保存在BeanFactory里面,false:表示目标实例非单例,每次都会创建一个新的目标bean实例出来。     *     * @return     */    public boolean isSingleton() {        return true;    }}
package model;/** * @author zxz * 目标实例 */public class Car {    private String brand;    private int price;    public Car(String brand, int price) {        this.brand = brand;        this.price = price;}

  1. 将CarFactoryBean通过配置的方式注入到BeanFactory里面,具体配置如下。
<?xml version="1.0" encoding="UTF-8"?>

  1. 测试用例。
import model.Car;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/** * @author zxz */public class JuniteTest {    @Test    public void testBeanPostProcessor() {        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");        Car car = (Car) context.getBean("car");        System.out.println("brand: " + car.getBrand() + " , price: " + car.getPrice());    }}

  1. 测试用例比较简单,我们来看下Car实例创建原理是什么样子的吧?回到上一篇文章的preInstantiateSingletons()方法。接着看创建完RootBeanDefinition定义之后的逻辑。
public void preInstantiateSingletons() throws BeansException {      if (this.logger.isDebugEnabled()) {          this.logger.debug("Pre-instantiating singletons in " + this);      }      // Iterate over a copy to allow for init methods which in turn register new bean definitions.      // While this may not be part of the regular factory bootstrap, it does otherwise work fine.      List beanNames = new ArrayList<>(this.beanDefinitionNames);      // Trigger initialization of all non-lazy singleton beans...      for (String beanName : beanNames) {          RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);          if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {              // 就是这里,判断当前的beanName对应的bean是否是一个FactoryBean。              if (isFactoryBean(beanName)) {                  // 如果是一个FactoryBean,则获取对应的FactoryBean实例。                  Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);                  if (bean instanceof FactoryBean) {                      final FactoryBean> factory = (FactoryBean>) bean;                      boolean isEagerInit;                      if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {                          isEagerInit = AccessController.doPrivileged((PrivilegedAction)                                          ((SmartFactoryBean>) factory)::isEagerInit,                                  getAccessControlContext());                      }                      else {                          isEagerInit = (factory instanceof SmartFactoryBean &&                                  ((SmartFactoryBean>) factory).isEagerInit());                      }                      if (isEagerInit) {                          getBean(beanName);                      }                  }              }              else {                  getBean(beanName);              }          }      }      // Trigger post-initialization callback for all applicable beans...      for (String beanName : beanNames) {          Object singletonInstance = getSingleton(beanName);          if (singletonInstance instanceof SmartInitializingSingleton) {              final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;              if (System.getSecurityManager() != null) {                  AccessController.doPrivileged((PrivilegedAction) () -> {                      smartSingleton.afterSingletonsInstantiated();                      return null;                  }, getAccessControlContext());              }              else {                  smartSingleton.afterSingletonsInstantiated();              }          }      }}

  1. 来看看isFactoryBean()是怎么根据beanName判断是否是一个FactoryBean。
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {      // Step1:解析名字,之前的文章分析过,忘记的朋友翻翻原来的文章。      String beanName = transformedBeanName(name);      // Step2:根据beanName从缓存中获取对应的bean实例。这个时候缓存里面肯定没有,所以这里返回空。      Object beanInstance = getSingleton(beanName, false);      if (beanInstance != null) {          // Step3:如果缓存能取到则直接返回。          return (beanInstance instanceof FactoryBean);      }      // No singleton instance found -> check bean definition.      // Step4:如果当前BeanFactory不存在对应的BeanDefinition定义 && 获取父BeanFactory并且如果实现了ConfigurableBeanFactory,则从父BeanFactory判断beanName是否是一个FactoryBean。      if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {          // No bean definition found in this factory -> delegate to parent.          return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);      }      // Step5:根据beanName和RootBeanDefinition判断是否是FactoryBean。      return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));}
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {      // Step1:获取beanName对应的Class类型      Class> beanType = predictBeanType(beanName, mbd, FactoryBean.class);      // Step2:class类型不为null && class类型是通过FactoryBean分配的。则认为是一个FactoryBean,isAssignableFrom()是一个native方法。      return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));}

  1. 接着来看下beanName对应的Class类型是如何获取到的,此处调用的AbstractAutowireCapableBeanFactory.predictBeanType()方法。
protected Class> predictBeanType(String beanName, RootBeanDefinition mbd, Class>... typesToMatch) {      // Step1:根据beanName和mbd确定目标类型      Class> targetType = determineTargetType(beanName, mbd, typesToMatch);      // Apply SmartInstantiationAwareBeanPostProcessors to predict the      // eventual type after a before-instantiation shortcut.      // Step2:如果获取到了对应的class类型 && mbd是合成的 && 存在InstantiationAwareBeanPostProcessors(我们这里没有,所以if条件不成立)      if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {          // Step2.1:遍历所有的BeanPostProcessor来获取对应的class类型          for (BeanPostProcessor bp : getBeanPostProcessors()) {              if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {                  SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;                  Class> predicted = ibp.predictBeanType(targetType, beanName);                  if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] ||                          FactoryBean.class.isAssignableFrom(predicted))) {                      return predicted;                  }              }          }      }      // Step3:返回获取到的class类型      return targetType;}

  1. 来看看class类型是怎么被确定下来的。
protected Class> determineTargetType(String beanName, RootBeanDefinition mbd, Class>... typesToMatch) {      // Step1:通过mbd(RootBeanDefinition定义)获取class类型。      Class> targetType = mbd.getTargetType();      if (targetType == null) {          // Step2:通过mbd指定的factory获取对应的class类型,如果没有指定Factory,则通过resolveBeanClass获取class类型。          targetType = (mbd.getFactoryMethodName() != null ?                  getTypeForFactoryMethod(beanName, mbd, typesToMatch) :                  resolveBeanClass(mbd, beanName, typesToMatch));          if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) {              mbd.resolvedTargetType = targetType;          }      }      // Step3:返回class类型。      return targetType;}

  1. 接着来看看如何从resolveBeanClass()中获取到class类型。
protected Class> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class>... typesToMatch)throws CannotLoadBeanClassException {      try {          // Step1:mbd如果指定了class类型,则直接返回该class类型。          if (mbd.hasBeanClass()) {              return mbd.getBeanClass();          }          // Step2:如果有安全检查,优先优先做安全检查,然后通过doResolveBeanClass获取到class类型并返回。          if (System.getSecurityManager() != null) {              return AccessController.doPrivileged((PrivilegedExceptionAction>) () ->                  doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());          }          else {              return doResolveBeanClass(mbd, typesToMatch);          }      }      catch (PrivilegedActionException pae) {          ClassNotFoundException ex = (ClassNotFoundException) pae.getException();          throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);      }      catch (ClassNotFoundException ex) {          throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);      }      catch (LinkageError err) {          throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);      }}

  1. 接着看看doResolveBeanClass()的真正实现,FactoryBean对应的class类型也是从这里确定的。
private Class> doResolveBeanClass(RootBeanDefinition mbd, Class>... typesToMatch)throws ClassNotFoundException {      // Step1:获取ClassLoader      ClassLoader beanClassLoader = getBeanClassLoader();      ClassLoader classLoaderToUse = beanClassLoader;      // Step2:如果指定了要获取class类型,则获取对应的模板classLoader,我们这没有,可以忽略该方法。      if (!ObjectUtils.isEmpty(typesToMatch)) {          // When just doing type checks (i.e. not creating an actual instance yet),          // use the specified temporary class loader (e.g. in a weaving scenario).          ClassLoader tempClassLoader = getTempClassLoader();          if (tempClassLoader != null) {              classLoaderToUse = tempClassLoader;              if (tempClassLoader instanceof DecoratingClassLoader) {                  DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;                  for (Class> typeToMatch : typesToMatch) {                      dcl.excludeClass(typeToMatch.getName());                  }              }          }      }      // Step3:获取RootBeanDefinition定义的class名字      String className = mbd.getBeanClassName();      if (className != null) {          // Step3.1:根据类名和mbd计算一个结果用来比较,由于我们测试用例指定的比较简单,所以这里返回的名字肯定和className相同。这个方法执行了一些表达式计算,具体内容可自行了解。          Object evaluated = evaluateBeanDefinitionString(className, mbd);          if (!className.equals(evaluated)) {              // A dynamically resolved expression, supported as of 4.2...              if (evaluated instanceof Class) {                  return (Class>) evaluated;              }              else if (evaluated instanceof String) {                  return ClassUtils.forName((String) evaluated, classLoaderToUse);              }              else {                  throw new IllegalStateException("Invalid class name expression result: " + evaluated);              }          }          // When resolving against a temporary class loader, exit early in order          // to avoid storing the resolved Class in the bean definition.          if (classLoaderToUse != beanClassLoader) {              return ClassUtils.forName(className, classLoaderToUse);          }      }      // Step4:利用Class.forName返回一个Class类型。      return mbd.resolveBeanClass(beanClassLoader);}

总结

到此我们就获取到了beanName对应的class类型,从而判断其是否是一个FactoryBean。有些朋友看到这里应该会比较迷惑BeanFactory和FactoryBean,这里简单给大家解释一下。

  • BeanFactory:是一个Bean工厂,是一个IoC容易,用于存放Bean实例的。
  • FactoryBean:它本身是一种特殊的bean,通过FactoryBean可以创建出指定的bean实例,即调用其getObject()获得。所以也就是BeanFactory是用来管理FactoryBean的。

注意

  1. 在xml文件中我们指定的是FactoryBean,而非目标Bean
  2. 通过context.getBean("car")方式获取到的bean实例是目标bean,如果我们想要的是FactoryBean本身,而非目标bean实例,则通过context.getBean("&car")就可以获得。
  3. FactoryBean的getObject()方法是在第一次getBean的时候才会被调用,如果isSingleton()方法返回true,则下次使用时直接从BeanFactory里面获取。
82a98f04b1628cbc38e169c69c9d4080.png

感谢大家的支持,多多转发关注不迷路哈~~~~~~~~~~~~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值