spring 簡單Bean 實例化過程

說明:本文只介紹簡單的bean實例化過程体谒,沒有注入抒痒,沒有代理等等

實例

代碼

@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());
    }
}

運行結(jié)果

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

spring Bean 實例化過程

本文只針對 實例GoodsService 實例化過程進行描述傀广,實例化前簡單描述:spring 把 GoodsService 類信息保存到BeanDefinition伪冰,實例化時從BeanDefinition中讀取類信息進行實例化

1贮聂、實例化開始

首先打開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實例:不是抽象類 && 是單例 && 不是懶加載
            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實例
                    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();
                }
            }
        }
    }

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

批注 2020-03-29 171730.png

beanNames 進行循環(huán)遍歷并進行實例化兰伤,此時我們只關(guān)心 goodsService 實例化過程敦腔。

第二符衔,獲取 goodsServiceRootBeanDefinition 此時的 RootBeanDefinition 是一個 MergedLocalBeanDefinition 即和并了父類 相關(guān)信息的 BeanDefinition 判族,檢測bd對應(yīng)的Bean實例:不是抽象類 && 是單例 && 不是懶加載形帮,因為 goodsService 不是 FactoryBean 則直接執(zhí)行 getBean(beanName) 獲取bean 實例沃缘,詳細(xì)過程請查看 2槐臀、獲取beangetBean(beanName) 已經(jīng)把bean 實例化并緩存到單例池中,本方法的第二個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;

   // 首先檢查單例緩存中手動注冊的單例對象华畏。(此處會涉及到注入的邏輯亡笑,本次沒有注入不過多關(guān)注)况芒,因為goodsService還沒有被創(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)建這個bean實例:
      // 如果該bean正在創(chuàng)建則拋出異常
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }

      // 檢查這個父工廠中是否存在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要創(chuàng)建了: 從 mergedBeanDefinitions 中刪除落君,在 alreadyCreated 中添加
         // 讓bean定義重新合并绎速,現(xiàn)在我們實際上是在創(chuàng)建bean…以防在此期間它的一些元數(shù)據(jù)發(fā)生變化纹冤。
         // 并把 goodsService 加入到 alreadyCreated 集合中
         markBeanAsCreated(beanName);
      }

      try {
         // 重新合并 goodsService 以防在此期間它的一些元數(shù)據(jù)發(fā)生變化萌京。
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         // 檢查 MergedBeanDefinition知残,其實就是檢查 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注冊一個從屬bean强挫,在銷毀給定bean之前銷毀它呆细。dep 和 beanName 分別在兩個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 實例 檢測是否是單例模式
         if (mbd.isSingleton()) {
            // 此處調(diào)用 getSingleton 方法 傳遞了兩個參數(shù)坑夯,一個是 beanName, 另一個是 ObjectFactory 的實現(xiàn)類柜蜈,ObjectFactory 只有一個抽象方法 getObject() 淑履,所以當(dāng)執(zhí)行到 ObjectFactory.getObject() 時秘噪,其實執(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ī)范名稱跟狱。因為 goodsService 沒有使用別名并且是一個普通的類驶臊,所以最終轉(zhuǎn)換的結(jié)果還是 goodsService 关翎。

第二纵寝,從緩存中獲取共享實例爽茴,因為 goodsService 是首次創(chuàng)建所以 Object sharedInstance = null 進入到 else 分支

第三室奏,檢測如果 goodsService 正在實例化則拋出異常

第四窍奋,獲取父工廠江场,這里邊拋出一個問題: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)在我們實際上是在創(chuàng)建bean…以防在此期間它的一些元數(shù)據(jù)發(fā)生變化扯俱。
                    clearMergedBeanDefinition(beanName);
                    this.alreadyCreated.add(beanName);
                }
            }
        }
    }

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

第七读存,獲取 goodsService 初始化所需要的依賴让簿,此時 String[] dependsOn = null

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

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

此處可以獲取單例對象

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

3牛郑、獲取單例對象

根據(jù) beanName 名稱返回注冊的單例對象,如果沒有則創(chuàng)建并注冊一個新的單例對象钉答。方法的全路徑名是 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) {
                    // 把實例放入緩存中
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

首先惶楼,加同步鎖何陆,再次從單例緩存池 singletonObjects 中獲取單例贷盲,如果不為null 則直接返回巩剖,此時為 null

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

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

第四仙畦,執(zhí)行 singletonObject = singletonFactory.getObject();2慨畸、獲取bean第八 步 的 lambda 表達式寸士, 即 執(zhí)行 createBean(beanName, mbd, args) 該方法的具體執(zhí)行流程請查看 4、創(chuàng)建bean婶博,這個行代碼將會獲得單例對象 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)建前的一次后置處理器,返回一個對象碧绞,如果該對象不為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深拷貝一個新的RootBeanDefinition副本嵌削,并且將解析的Class賦值給拷貝的RootBeanDefinition副本beanClass屬性毛好,
            // 該拷貝副本取代mdb用于后續(xù)的操作
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }
    
        try {
            // 對override屬性進行標(biāo)記及驗證
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // 實例化前的處理,給beanpostprocessor(InstantiationAwareBeanPostProcessor)一個機會返回代理對象來替代真正的bean實例,達到“短路”效果
            // 第一次調(diào)用后置處理器
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            // 如果bean不為空飒箭,則會跳過Spring默認(rèn)的實例化過程,直接使用返回的bean
            // 此時 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實例(真正創(chuàng)建Bean的方法)
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            // 返回創(chuàng)建的Bean實例
            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屬性進行標(biāo)記及驗證

第三呢堰,實例化前調(diào)用 beanpostprocessor ( InstantiationAwareBeanPostProcessor) 后置處理器返回代理對象來替代真正的bean實例,第一次實例化前調(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 單例

該方法實際創(chuàng)建指定的bean阁将。在這一點上,預(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實例的緩存
            // 因為 goodsService 是一個普通的類窘哈,所以此處instanceWrapper = null
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            // 根據(jù)beanName吹榴、mbd、args滚婉,使用對應(yīng)的策略創(chuàng)建Bean實例图筹,并返回包裝類BeanWrapper
            /*
            * 第二次調(diào)用后置處理器
            * 創(chuàng)建bean實例,并將實例放在包裝類BeanWrapper中返回
            * 1满哪、通過工廠方法創(chuàng)建bean實例
            * 2婿斥、通過構(gòu)造方法自動注入創(chuàng)建bean實例
            * 3劝篷、通過無參構(gòu)造器創(chuàng)建bean實例
            * */
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        // 拿到創(chuàng)建好的Bean實例
        final Object bean = instanceWrapper.getWrappedInstance();
        // 拿到Bean實例的類型
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        // 允許后處理程序修改合并的bean定義。
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    // 應(yīng)用后置處理器MergedBeanDefinitionPostProcessor民宿,允許修改MergedBeanDefinition娇妓,
                    // Autowired注解正是通過此方法實現(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ā)時也是如此哈恰。
        // 判斷是否需要提早曝光實例:單例 && 允許循環(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實例。
        Object exposedObject = bean;
        try {
            // 對bean進行屬性填充锌云;其中荠医,可能存在依賴于其他bean的屬性,則會遞歸初始化依賴的bean實例
            // 第五次桑涎、第六次調(diào)用后置處理器
            populateBean(beanName, mbd, instanceWrapper);
            // 對bean進行初始化
            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) {
            // 如果允許提前曝光實例彬向,則進行循環(huán)依賴檢查
            Object earlySingletonReference = getSingleton(beanName, false);
            // earlySingletonReference只有在當(dāng)前解析的bean存在循環(huán)依賴的情況下才會不為空
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    // 如果exposedObject沒有在initializeBean方法中被增強,則不影響之前的循環(huán)引用
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    // 如果exposedObject在initializeBean方法中被增強 && 不允許在循環(huán)引用的情況下使用注入原始bean實例
                    // && 當(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的實例攻冷,因為這些bean依賴的bean已經(jīng)被增強了娃胆,他們依賴的bean相當(dāng)于臟數(shù)據(jù)
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            // 移除失敗的添加到 actualDependentBeans
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        // 如果存在移除失敗的,則拋出異常等曼,因為存在bean依賴了“臟數(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實例的緩存州泊,因為 goodsService 是一個普通的bean 别厘,所以 this.factoryBeanInstanceCache.remove(beanName) 執(zhí)行的結(jié)果為 null

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

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // 確保此時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實例的回調(diào)(如果有的話)。
        // instanceSupplier = null
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }

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

        // Shortcut when re-creating the same bean...
        // 英文注釋翻譯:重新創(chuàng)建相同的bean時的快捷方式…
        // resolved: 構(gòu)造函數(shù)或工廠方法是否已經(jīng)解析過
        boolean resolved = false;
        // autowireNecessary: 是否需要自動注入(即是否需要解析構(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判斷是否需要自動注入
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        // 因為 mbd.resolvedConstructorOrFactoryMethod = null 所以 resolved = false,程序不會進入 if 分支
        if (resolved) {
            // 如果已經(jīng)解析過,則使用resolvedConstructorOrFactoryMethod緩存里解析好的構(gòu)造函數(shù)方法
            if (autowireNecessary) {
                // 需要自動注入没讲,則執(zhí)行構(gòu)造函數(shù)自動注入
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                // 否則使用默認(rèn)的構(gòu)造函數(shù)進行bean的實例化
                return instantiateBean(beanName, mbd);
            }
        }

        // 應(yīng)用后置處理器SmartInstantiationAwareBeanPostProcessor眯娱,可以得到bean的候選構(gòu)造函數(shù),如@Autowire 注解的構(gòu)造方法爬凑, 然后使用該構(gòu)造函數(shù)進行創(chuàng)建對象徙缴。
        // 自動裝配的候選者構(gòu)造器 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
        // 第二次調(diào)用后置處理器,這個方法用來推斷構(gòu)造函數(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ù)自動注入
            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ù)進行bean的實例化
        // 即無參構(gòu)造器 通過反射調(diào)用無參構(gòu)造函數(shù)進行創(chuàng)建
        return instantiateBean(beanName, mbd);
    }

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

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

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

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

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

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

第八,即第七次調(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)系作者
  • 序言:七十年代末精盅,一起剝皮案震驚了整個濱河市帽哑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌叹俏,老刑警劉巖妻枕,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡屡谐,警方通過查閱死者的電腦和手機述么,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來愕掏,“玉大人度秘,你說我怎么就攤上這事⊥ふ洌” “怎么了敷钾?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肄梨。 經(jīng)常有香客問我阻荒,道長,這世上最難降的妖魔是什么众羡? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任侨赡,我火速辦了婚禮,結(jié)果婚禮上粱侣,老公的妹妹穿的比我還像新娘羊壹。我一直安慰自己,他們只是感情好齐婴,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布油猫。 她就那樣靜靜地躺著,像睡著了一般柠偶。 火紅的嫁衣襯著肌膚如雪情妖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天诱担,我揣著相機與錄音毡证,去河邊找鬼。 笑死蔫仙,一個胖子當(dāng)著我的面吹牛料睛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播摇邦,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼恤煞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了施籍?” 一聲冷哼從身側(cè)響起阱州,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎法梯,沒想到半個月后苔货,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體犀概,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年夜惭,在試婚紗的時候發(fā)現(xiàn)自己被綠了姻灶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡诈茧,死狀恐怖产喉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情敢会,我是刑警寧澤曾沈,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站鸥昏,受9級特大地震影響塞俱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吏垮,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一障涯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧膳汪,春花似錦唯蝶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至痹换,卻和暖如春征字,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晴音。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缔杉,地道東北人锤躁。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像或详,于是被迫代替她去往敵國和親系羞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容