spring 簡單Bean 實(shí)例化過程

說明:本文只介紹簡單的bean實(shí)例化過程,沒有注入,沒有代理等等

實(shí)例

代碼

@Service
public class GoodsService {

    public List<String> list() {
        return Arrays.asList("apple");
    }
}

@Configuration
@ComponentScan("com.yunfan.bean.instantiation.simple")
public class SimpleConfig {

}

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SimpleConfig.class);

        GoodsService goodsService = (GoodsService) applicationContext.getBean("goodsService");
        System.out.println(goodsService.list());
    }
}

運(yùn)行結(jié)果

> Task :spring-study:MainTest.main()
[apple]

spring Bean 實(shí)例化過程

本文只針對 實(shí)例GoodsService 實(shí)例化過程進(jìn)行描述,實(shí)例化前簡單描述:spring 把 GoodsService 類信息保存到BeanDefinition,實(shí)例化時(shí)從BeanDefinition中讀取類信息進(jìn)行實(shí)例化

1、實(shí)例化開始

首先打開spring源碼 DefaultListableBeanFactory 類的preInstantiateSingletons 方法 , 全路徑:org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

@Override
    public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("Pre-instantiating singletons in " + this);
        }
        // 獲取所有BeanDefinition的集合
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        // 觸發(fā)所有非惰性單例bean的初始化…
        for (String beanName : beanNames) {
            // 獲取beanName對應(yīng)的 MergedBeanDefinition, MergedBeanDefinition合并了 子類和父類的信息
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // bd對應(yīng)的Bean實(shí)例:不是抽象類 && 是單例 && 不是懶加載
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // 判斷beanName對應(yīng)的bean是否為FactoryBean
                if (isFactoryBean(beanName)) {
                    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<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {
                    // 如果beanName對應(yīng)的bean不是FactoryBean,只是普通Bean,通過beanName獲取bean實(shí)例
                    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<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

首先,拷貝一個(gè)容器中所有 BeanDefinition 的名稱到beanNames的List集合中, list中的內(nèi)容如圖:

批注 2020-03-29 171730.png

beanNames 進(jìn)行循環(huán)遍歷并進(jìn)行實(shí)例化,此時(shí)我們只關(guān)心 goodsService 實(shí)例化過程。

第二,獲取 goodsServiceRootBeanDefinition 此時(shí)的 RootBeanDefinition 是一個(gè) MergedLocalBeanDefinition 即和并了父類 相關(guān)信息的 BeanDefinition ,檢測bd對應(yīng)的Bean實(shí)例:不是抽象類 && 是單例 && 不是懶加載,因?yàn)?goodsService 不是 FactoryBean 則直接執(zhí)行 getBean(beanName) 獲取bean 實(shí)例,詳細(xì)過程請查看 2、獲取bean ,getBean(beanName) 已經(jīng)把bean 實(shí)例化并緩存到單例池中,本方法的第二個(gè)for 循環(huán) 并并沒有對本次流程產(chǎn)生任何影響

2、獲取 bean

方法 getBean(beanName) 調(diào)用了 doGetBean 方法

@Override
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}

方法 doGetBean 的全路徑是 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
   // 返回bean名稱,去掉工廠取消引用前綴,并將別名解析為規(guī)范名稱。
   final String beanName = transformedBeanName(name);
   Object bean;

   // 首先檢查單例緩存中手動(dòng)注冊的單例對象。(此處會(huì)涉及到注入的邏輯,本次沒有注入不過多關(guān)注),因?yàn)間oodsService還沒有被創(chuàng)建所以此處sharedInstance為null
   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 + "'");
         }
      }
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }

   else {
      // 緩存中沒有,創(chuàng)建這個(gè)bean實(shí)例:
      // 如果該bean正在創(chuàng)建則拋出異常
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }

      // 檢查這個(gè)父工廠中是否存在bean定義。本次執(zhí)行過程中parentBeanFactory 為 null
      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);
         }
      }

      if (!typeCheckOnly) {
         // 標(biāo)記bean要?jiǎng)?chuàng)建了: 從 mergedBeanDefinitions 中刪除,在 alreadyCreated 中添加
         // 讓bean定義重新合并,現(xiàn)在我們實(shí)際上是在創(chuàng)建bean…以防在此期間它的一些元數(shù)據(jù)發(fā)生變化。
         // 并把 goodsService 加入到 alreadyCreated 集合中
         markBeanAsCreated(beanName);
      }

      try {
         // 重新合并 goodsService 以防在此期間它的一些元數(shù)據(jù)發(fā)生變化。
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         // 檢查 MergedBeanDefinition,其實(shí)就是檢查 goodsService 是否為抽象類,如果是則拋出異常
         checkMergedBeanDefinition(mbd, beanName, args);

         // 保證當(dāng)前bean所依賴的bean的初始化。 (goodsService 沒有依賴注入,所以 dependsOn 為 null)
         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 + "'");
               }
               // 為給定bean注冊一個(gè)從屬bean,在銷毀給定bean之前銷毀它。dep 和 beanName 分別在兩個(gè)Map中 建立關(guān)聯(lián)關(guān)系,表示他們之間的依賴關(guān)系
               registerDependentBean(dep, beanName);
               try {
                  getBean(dep);
               }
               catch (NoSuchBeanDefinitionException ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
            }
         }

         // 創(chuàng)建bean 實(shí)例 檢測是否是單例模式
         if (mbd.isSingleton()) {
            // 此處調(diào)用 getSingleton 方法 傳遞了兩個(gè)參數(shù),一個(gè)是 beanName, 另一個(gè)是 ObjectFactory 的實(shí)現(xiàn)類,ObjectFactory 只有一個(gè)抽象方法 getObject() ,所以當(dāng)執(zhí)行到 ObjectFactory.getObject() 時(shí),其實(shí)執(zhí)行的是 createBean(beanName, mbd, args);
            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;
               }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }

         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);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }

         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);
                  }
               });
               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());
      }
   }
   return (T) bean;
}

首先,轉(zhuǎn)換 bean 的名稱,去掉工廠引用前綴,并將別名解析為規(guī)范名稱。因?yàn)?goodsService 沒有使用別名并且是一個(gè)普通的類,所以最終轉(zhuǎn)換的結(jié)果還是 goodsService

第二,從緩存中獲取共享實(shí)例,因?yàn)?goodsService 是首次創(chuàng)建所以 Object sharedInstance = null 進(jìn)入到 else 分支

第三,檢測如果 goodsService 正在實(shí)例化則拋出異常

第四,獲取父工廠,這里邊拋出一個(gè)問題:spring的父、子 工廠? 當(dāng)前 parentBeanFactory = null , 所以不走 if 分支,走 else 分支

第五,標(biāo)記 beangoodsService 要被創(chuàng)建, 從 mergedBeanDefinitions 集合中刪除(讓bean定義重新合并,現(xiàn)在是在創(chuàng)建bean…以防在此期間它的一些元數(shù)據(jù)發(fā)生變化。) ,加入到 alreadyCreated 集合中

protected void markBeanAsCreated(String beanName) {
        if (!this.alreadyCreated.contains(beanName)) {
            synchronized (this.mergedBeanDefinitions) {
                if (!this.alreadyCreated.contains(beanName)) {
                    // 讓bean定義重新合并,現(xiàn)在我們實(shí)際上是在創(chuàng)建bean…以防在此期間它的一些元數(shù)據(jù)發(fā)生變化。
                    clearMergedBeanDefinition(beanName);
                    this.alreadyCreated.add(beanName);
                }
            }
        }
    }

第六,重新合并 MergedBeanDefinition 并檢測是不是抽象類

第七,獲取 goodsService 初始化所需要的依賴,此時(shí) String[] dependsOn = null

第八,判斷 goodsService 是否為單例 mbd.isSingleton() = true , 所以調(diào)用 getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法, 下面的代碼 是 ObjectFactory 接口的實(shí)現(xiàn)類,大括號 {...} 中便是 T getObject() 的實(shí)現(xiàn)方法,即調(diào)用 singletonFactory.getObject() 方法時(shí) 便是執(zhí)行大括號里邊的代碼 。獲取單例的具體流程請查看 **3、獲取單例對象 **

() -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    }

此處可以獲取單例對象

第八,調(diào)用 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); getObjectForBeanInstance 會(huì)先調(diào)用 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getObjectForBeanInstance 在該方法中 需要注意 registerDependentBean(beanName, currentlyCreatedBean); 這一行,當(dāng)然,本次流程不會(huì)執(zhí)行這行代碼,然后調(diào)用 org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance 這個(gè)方法,在本次流程中bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 這行代碼并沒有對 sharedInstance 做任何修改。返回單例對象

3、獲取單例對象

根據(jù) beanName 名稱返回注冊的單例對象,如果沒有則創(chuàng)建并注冊一個(gè)新的單例對象。方法的全路徑名是 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                // 判斷當(dāng)前是否正在銷毀單例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 + "'");
                }
                // 檢測創(chuàng)建的bean 是否在排除創(chuàng)建的集合中(如果在則拋出異常) 和 將beanName 加入 singletonsCurrentlyInCreation (正在創(chuàng)建的bean的集合)
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                // 被抑制的異常列表
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    // singletonFactory 生產(chǎn)bean
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    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;
                    }
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    // 把實(shí)例放入緩存中
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

首先,加同步鎖,再次從單例緩存池 singletonObjects 中獲取單例,如果不為null 則直接返回,此時(shí)為 null

第二,判斷當(dāng)前是否正在銷毀 單例 ,如果是則拋出異常

第三,檢測創(chuàng)建的bean 是否在排除創(chuàng)建的集合中(如果在則拋出異常), 將beanName 加入 singletonsCurrentlyInCreation (正在創(chuàng)建的bean的集合)

第四,執(zhí)行 singletonObject = singletonFactory.getObject();2、獲取bean第八 步 的 lambda 表達(dá)式, 即 執(zhí)行 createBean(beanName, mbd, args) 該方法的具體執(zhí)行流程請查看 4、創(chuàng)建bean,這個(gè)行代碼將會(huì)獲得單例對象 singletonObject = GoodsService@1654 并設(shè)置 newSingleton = true;

第五,執(zhí)行 afterSingletonCreation(beanName) 將 beanName 從 singletonsCurrentlyInCreation 集合中移除

第六,執(zhí)行 addSingleton(beanName, singletonObject) 該方法的代碼如下:

protected void addSingleton(String beanName, Object singletonObject) {
        synchronized (this.singletonObjects) {
            this.singletonObjects.put(beanName, singletonObject);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }

返回單例對象

4、解析bean并首次調(diào)用后置處理器

該方法執(zhí)行單例創(chuàng)建前的一次后置處理器,返回一個(gè)對象,如果該對象不為null,則直接返回, 如果為 null 則執(zhí)行 doCreateBean 方法,完成真正的單例的創(chuàng)建

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;
        // 解析beanName對應(yīng)的Bean的類型
        // resolvedClass = com.yunfan.bean.instantiation.simple.GoodsService
        // mbd.hasBeanClass() = true
        // mbd.getBeanClassName() = com.yunfan.bean.instantiation.simple.GoodsService
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            // 如果resolvedClass存在,并且mdb不存在beanClass即類型不是Class,并且mdb的beanClassName不為空(則代表beanClass存的是Class的name),
            // 則使用mdb深拷貝一個(gè)新的RootBeanDefinition副本,并且將解析的Class賦值給拷貝的RootBeanDefinition副本beanClass屬性,
            // 該拷貝副本取代mdb用于后續(xù)的操作
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }
    
        try {
            // 對override屬性進(jìn)行標(biāo)記及驗(yàn)證
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // 實(shí)例化前的處理,給beanpostprocessor(InstantiationAwareBeanPostProcessor)一個(gè)機(jī)會(huì)返回代理對象來替代真正的bean實(shí)例,達(dá)到“短路”效果
            // 第一次調(diào)用后置處理器
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            // 如果bean不為空,則會(huì)跳過Spring默認(rèn)的實(shí)例化過程,直接使用返回的bean
            // 此時(shí) bean = null
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }

        try {
            // 創(chuàng)建Bean實(shí)例(真正創(chuàng)建Bean的方法)
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            // 返回創(chuàng)建的Bean實(shí)例
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }

首先,解析beanName(goodsService)對應(yīng)的Bean的類型,resolvedClass = com.yunfan.bean.instantiation.simple.GoodsService

第二,對override屬性進(jìn)行標(biāo)記及驗(yàn)證

第三,實(shí)例化前調(diào)用 beanpostprocessor ( InstantiationAwareBeanPostProcessor) 后置處理器返回代理對象來替代真正的bean實(shí)例,第一次實(shí)例化前調(diào)用 后置處理器,返回結(jié)果 Object bean = null 繼續(xù)向下執(zhí)行,如果bean 不為 null 則直接返回。

第四,調(diào)用 doCreateBean 方法創(chuàng)建單例,該方法是真正的創(chuàng)建單例,然后返回單例。想要了解 doCreateBean 的具體流程請查看 5、真正創(chuàng)建bean單例, 返回單例

5、創(chuàng)建 bean 單例

該方法實(shí)際創(chuàng)建指定的bean。在這一點(diǎn)上,預(yù)創(chuàng)建處理已經(jīng)發(fā)生了,例如檢查{@code postProcessBeforeInstantiation}回調(diào)。

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

        // 新建Bean包裝類
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            // 如果是FactoryBean,則需要先移除未完成的FactoryBean實(shí)例的緩存
            // 因?yàn)?goodsService 是一個(gè)普通的類,所以此處instanceWrapper = null
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            // 根據(jù)beanName、mbd、args,使用對應(yīng)的策略創(chuàng)建Bean實(shí)例,并返回包裝類BeanWrapper
            /*
            * 第二次調(diào)用后置處理器
            * 創(chuàng)建bean實(shí)例,并將實(shí)例放在包裝類BeanWrapper中返回
            * 1、通過工廠方法創(chuàng)建bean實(shí)例
            * 2、通過構(gòu)造方法自動(dòng)注入創(chuàng)建bean實(shí)例
            * 3、通過無參構(gòu)造器創(chuàng)建bean實(shí)例
            * */
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        // 拿到創(chuàng)建好的Bean實(shí)例
        final Object bean = instanceWrapper.getWrappedInstance();
        // 拿到Bean實(shí)例的類型
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        // 允許后處理程序修改合并的bean定義。
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    // 應(yīng)用后置處理器MergedBeanDefinitionPostProcessor,允許修改MergedBeanDefinition,
                    // Autowired注解正是通過此方法實(shí)現(xiàn)注入類型的預(yù)解析
                    // 允許后置處理器修改合并的bean定義 MergedBeanDefinitionPostProcessor
                    // 第三次調(diào)用后置處理器
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        // 急切地緩存單例,以便能夠解析循環(huán)引用,甚至在由生命周期接口(如BeanFactoryAware)觸發(fā)時(shí)也是如此。
        // 判斷是否需要提早曝光實(shí)例:單例 && 允許循環(huán)依賴 && 當(dāng)前bean正在創(chuàng)建中
        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");
            }
            // 提前曝光beanName的ObjectFactory,用于解決循環(huán)引用
            // 應(yīng)用后置處理器SmartInstantiationAwareBeanPostProcessor,允許返回指定bean的早期引用,若沒有則直接返回bean
            // 解決循環(huán)依賴 SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
            // 第四次調(diào)用后置處理器
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // 初始化bean實(shí)例。
        Object exposedObject = bean;
        try {
            // 對bean進(jìn)行屬性填充;其中,可能存在依賴于其他bean的屬性,則會(huì)遞歸初始化依賴的bean實(shí)例
            // 第五次、第六次調(diào)用后置處理器
            populateBean(beanName, mbd, instanceWrapper);
            // 對bean進(jìn)行初始化
            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);
            }
        }

        if (earlySingletonExposure) {
            // 如果允許提前曝光實(shí)例,則進(jìn)行循環(huán)依賴檢查
            Object earlySingletonReference = getSingleton(beanName, false);
            // earlySingletonReference只有在當(dāng)前解析的bean存在循環(huán)依賴的情況下才會(huì)不為空
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    // 如果exposedObject沒有在initializeBean方法中被增強(qiáng),則不影響之前的循環(huán)引用
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    // 如果exposedObject在initializeBean方法中被增強(qiáng) && 不允許在循環(huán)引用的情況下使用注入原始bean實(shí)例
                    // && 當(dāng)前bean有被其他bean依賴

                    // 拿到依賴當(dāng)前bean的所有bean的beanName數(shù)組
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        // 嘗試移除這些bean的實(shí)例,因?yàn)檫@些bean依賴的bean已經(jīng)被增強(qiáng)了,他們依賴的bean相當(dāng)于臟數(shù)據(jù)
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            // 移除失敗的添加到 actualDependentBeans
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        // 如果存在移除失敗的,則拋出異常,因?yàn)榇嬖赽ean依賴了“臟數(shù)據(jù)”
                        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.");
                    }
                }
            }
        }

        // 將bean注冊為一次性的。
        try {
            // 注冊用于銷毀的bean,執(zhí)行銷毀操作的有三種:自定義destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
            // 將bean注冊為可以銷毀 DestructionAwareBeanPostProcessor bean的銷毀后置處理器
            // 第九次調(diào)用后置處理器
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        // 完成創(chuàng)建并返回
        return exposedObject;
    }

首先,先移除未完成的FactoryBean實(shí)例的緩存,因?yàn)?goodsService 是一個(gè)普通的bean ,所以 this.factoryBeanInstanceCache.remove(beanName) 執(zhí)行的結(jié)果為 null。

第二,創(chuàng)建 bean 實(shí)例,調(diào)用 createBeanInstance 方法。代碼如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // 確保此時(shí)bean類已經(jīng)被解析。
        // beanClass = class com.yunfan.bean.instantiation.simple.GoodsService
        Class<?> beanClass = resolveBeanClass(mbd, beanName);

        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            // beanClass不為空 && beanClass不是公開類(不是public修飾) && 該bean不允許訪問非公共構(gòu)造函數(shù)和方法,則拋異常
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        }

        // 返回創(chuàng)建bean實(shí)例的回調(diào)(如果有的話)。
        // instanceSupplier = null
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }

        // 如果存在工廠方法則使用工廠方法實(shí)例化bean對象
        // mbd.getFactoryMethodName() = null
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // Shortcut when re-creating the same bean...
        // 英文注釋翻譯:重新創(chuàng)建相同的bean時(shí)的快捷方式…
        // resolved: 構(gòu)造函數(shù)或工廠方法是否已經(jīng)解析過
        boolean resolved = false;
        // autowireNecessary: 是否需要自動(dòng)注入(即是否需要解析構(gòu)造函數(shù)參數(shù))
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                // mbd.resolvedConstructorOrFactoryMethod 用于緩存已解析構(gòu)造函數(shù)或工廠方法的包可見字段。
                // 此處 mbd.resolvedConstructorOrFactoryMethod = null
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    // 如果resolvedConstructorOrFactoryMethod緩存不為空,則將resolved標(biāo)記為已解析
                    resolved = true;
                    // 根據(jù)constructorArgumentsResolved判斷是否需要自動(dòng)注入
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        // 因?yàn)?mbd.resolvedConstructorOrFactoryMethod = null 所以 resolved = false,程序不會(huì)進(jìn)入 if 分支
        if (resolved) {
            // 如果已經(jīng)解析過,則使用resolvedConstructorOrFactoryMethod緩存里解析好的構(gòu)造函數(shù)方法
            if (autowireNecessary) {
                // 需要自動(dòng)注入,則執(zhí)行構(gòu)造函數(shù)自動(dòng)注入
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                // 否則使用默認(rèn)的構(gòu)造函數(shù)進(jìn)行bean的實(shí)例化
                return instantiateBean(beanName, mbd);
            }
        }

        // 應(yīng)用后置處理器SmartInstantiationAwareBeanPostProcessor,可以得到bean的候選構(gòu)造函數(shù),如@Autowire 注解的構(gòu)造方法, 然后使用該構(gòu)造函數(shù)進(jìn)行創(chuàng)建對象。
        // 自動(dòng)裝配的候選者構(gòu)造器 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
        // 第二次調(diào)用后置處理器,這個(gè)方法用來推斷構(gòu)造函數(shù),實(shí)際使用的實(shí)現(xiàn)SmartInstantiationAwareBeanPostProcessor接口的AutowiredAnnotationBeanPostProcess后置處理器去做的。
        // 此處 ctors = null
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        // AutowireMode設(shè)置為3,采用構(gòu)造器貪婪模式
        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
            // 如果ctors不為空 || mbd的注入方式為AUTOWIRE_CONSTRUCTOR || mdb定義了構(gòu)造函數(shù)的參數(shù)值 || args不為空,則執(zhí)行構(gòu)造函數(shù)自動(dòng)注入
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        // 默認(rèn)構(gòu)造的首選構(gòu)造函數(shù) ctors = null
        ctors = mbd.getPreferredConstructors();
        if (ctors != null) {
            return autowireConstructor(beanName, mbd, ctors, null);
        }

        // 沒有特殊處理,則使用默認(rèn)的構(gòu)造函數(shù)進(jìn)行bean的實(shí)例化
        // 即無參構(gòu)造器 通過反射調(diào)用無參構(gòu)造函數(shù)進(jìn)行創(chuàng)建
        return instantiateBean(beanName, mbd);
    }

createBeanInstance 方法中有一個(gè)第二次調(diào)用后置處理器,需要注意一下,即Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); 這個(gè)方法用來推斷構(gòu)造函數(shù),實(shí)際使用的實(shí)現(xiàn)SmartInstantiationAwareBeanPostProcessor 接口的AutowiredAnnotationBeanPostProcess 后置處理器去做的。

第三,第三次調(diào)用后置處理器 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 該方法實(shí)際調(diào)用了 MergedBeanDefinitionPostProcessor的 方法:postProcessMergedBeanDefinition,用來緩存注解信息。

第四,即第四次調(diào)用后置處理器 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 調(diào)用了 SmartInstantiationAwareBeanPostProcessor 后置處理器的 getEarlyBeanReference(exposedObject, beanName) 方法 ,這個(gè)方法是來解決循環(huán)依賴問題的

第五,即第五次調(diào)用后置處理器, 在 populateBean(beanName, mbd, instanceWrapper); 方法里調(diào)用了后置處理器 InstantiationAwareBeanPostProcessor 的方法 postProcessAfterInstantiation(bw.getWrappedInstance(), beanName) 判斷是否需要填充屬性,goodsService 需要填充的屬性個(gè)數(shù)為零,但并不是不允許修改bean的屬性,所以不會(huì)忽略直接返回

第六,即第六次調(diào)用后置處理器,在 populateBean(beanName, mbd, instanceWrapper); 方法里調(diào)用了后置處理器 InstantiationAwareBeanPostProcessor 的方法 postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); 進(jìn)行屬性填充前的處理

第七,即第七次調(diào)用后置處理器,在方法exposedObject = initializeBean(beanName, exposedObject, mbd)wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); 調(diào)用了 BeanPostProcessor 的方法 postProcessBeforeInitialization(result, beanName) 對bean實(shí)例進(jìn)行包裝

第八,即第七次調(diào)用后置處理器,在方法exposedObject = initializeBean(beanName, exposedObject, mbd)wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 調(diào)用了 BeanPostProcessor 的方法 postProcessAfterInitialization(result, beanName)

第九,即第九次調(diào)用后置處理器,在方法 registerDisposableBeanIfNecessary(beanName, bean, mbd); 中 將bean注冊為可以銷毀 DestructionAwareBeanPostProcessor bean的銷毀后置處理器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容