完全搞懂依賴注入(一)Bean實例建立過程

 

 

上一章介紹了Bean的加載過程(IOC初始化過程),加載完成後,緊接着就要用到它的依賴注入(IOC 依賴注入)。php

那什麼是依賴注入呢?java

所謂依賴注入,就是由IOC容器在運行期間,動態地將某種依賴關係注入到對象之中。再完成IOC容器初始化以後,也就是所謂的Bean加載完成後,咱們須要對這些Bean進行調用和獲取,這個過程就叫依賴注入。web

那何時會觸發依賴注入呢?spring

  1. 經過getBean()方法獲取Bean對象。緩存

  2. 給Bean配置了懶加載,ApplicationContext啓動完成後調用getBean()來實例化對象。安全

如今計算機性能已經足夠,不是特殊要求下儘可能別作懶加載,這樣的話能夠減小web運行時的調用時間開銷。session

好了,介紹完這些就開始咱們的DI之旅。app

1. BeanFactory

經過Spring獲取Bean的最根本的接口。ide

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

  1. // 若是myJndiObject時FactoryBean, 則 &myJndiObject 將返回工廠而不是返回實例。post

  2. String FACTORY_BEAN_PREFIX = "&";

  3. // 獲取bean實例

  4. Object getBean(String name) throws BeansException;

  5. // 判斷一個bean是否時單例

  6. boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

  7. // 判斷一個bean是不是原型

  8. boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

  9. // 檢查bean的name和type是否匹配

  10. boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;

  11. // 獲取bean類型

  12. Class<?> getType(String name) throws NoSuchBeanDefinitionException;

  13. // 獲取bean別名

  14. String[] getAliases(String name);

getBean()方法有不少重載方法,上面只總結了一個。這個方法是DI的入口方法,接下來會從這個方法開始往下研究。

2. AbstractBeanFactory

從名字也能看出,這是BeanFactory的抽象實現類。

  1. public Object getBean(String name) throws BeansException {

  2.    return doGetBean(name, null, null, false);

  3. }

doGetBean()方法也是該類中的方法。

  1. // 依賴注入 從這裏開始發生

  2. private <T> T doGetBean(

  3.        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)

  4.        throws BeansException {

  5.  

  6.    // 根據指定名字獲取被管理Bean的名稱

  7.    // 若是是別名, 則轉換爲真正的bean名

  8.    final String beanName = transformedBeanName(name);

  9.    Object bean;

  10.  

  11.    // Eagerly check singleton cache for manually registered singletons.

  12.    // 先從緩存中取單例 bean

  13.    Object sharedInstance = getSingleton(beanName);

  14.    if (sharedInstance != null && args == null) {

  15.        if (logger.isDebugEnabled()) {

  16.            // 若是有,則直接返回該bean

  17.            if (isSingletonCurrentlyInCreation(beanName)) {

  18.                logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +

  19.                        "' that is not fully initialized yet - a consequence of a circular reference");

  20.            }

  21.            else {

  22.                logger.debug("Returning cached instance of singleton bean '" + beanName + "'");

  23.            }

  24.        }

  25.        //獲取 bean 的實例對象

  26.        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

  27.    }

  28.  

  29.    else {

  30.        // Fail if we're already creating this bean instance:

  31.        // We're assumably within a circular reference.

  32.        // 若是不是單例對象, 並且 緩存中有原型模式bean, 就拋異常

  33.        if (isPrototypeCurrentlyInCreation(beanName)) {

  34.            throw new BeanCurrentlyInCreationException(beanName);

  35.        }

  36.  

  37.        // 檢查 BeanDefinition 是否再當前的factory中, 若是不在則委託父類容器取查找

  38.        // Check if bean definition exists in this factory.

  39.        BeanFactory parentBeanFactory = getParentBeanFactory();

  40.        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {

  41.            // Not found -> check parent.

  42.            String nameToLookup = originalBeanName(name);

  43.            if (args != null) {

  44.                // Delegation to parent with explicit args.

  45.                // 委託父類容器取找(名字+參數)

  46.                return (T) parentBeanFactory.getBean(nameToLookup, args);

  47.            }

  48.            else {

  49.                // 委託父類容器取找(名稱+類型)

  50.                // No args -> delegate to standard getBean method.

  51.                return parentBeanFactory.getBean(nameToLookup, requiredType);

  52.            }

  53.        }

  54.  

  55.        if (!typeCheckOnly) {

  56.            // 標記 bean 被建立

  57.            markBeanAsCreated(beanName);

  58.        }

  59.  

  60.        // 根據bean名稱獲取 父類的 beanDefinition, 合併繼承公共屬性

  61.        final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

  62.        checkMergedBeanDefinition(mbd, beanName, args);

  63.  

  64.        // Guarantee initialization of beans that the current bean depends on.

  65.        // 獲取當前bean 全部依賴Bean 的集合

  66.        String[] dependsOn = mbd.getDependsOn();

  67.        if (dependsOn != null) {

  68.            for (String dependsOnBean : dependsOn) {

  69.                // 遞歸調用, 獲取當前Bean的依賴Bean

  70.                getBean(dependsOnBean);

  71.                // 把依賴Bean註冊給當前的Bean

  72.                registerDependentBean(dependsOnBean, beanName);

  73.            }

  74.        }

  75.  

  76.        // Create bean instance.

  77.        // 建立bean 實例

  78.        if (mbd.isSingleton()) {

  79.            // 建立 bean 實例對象, 而且註冊給所依賴的對象

  80.            sharedInstance = getSingleton(beanName, new ObjectFactory() {

  81.                public Object getObject() throws BeansException {

  82.                    try {

  83.                        // 建立一個指定bean 實例對象

  84.                        return createBean(beanName, mbd, args);

  85.                    }

  86.                    catch (BeansException ex) {

  87.                        // Explicitly remove instance from singleton cache: It might have been put there

  88.                        // eagerly by the creation process, to allow for circular reference resolution.

  89.                        // Also remove any beans that received a temporary reference to the bean.

  90.                        // 清除該單例

  91.                        destroySingleton(beanName);

  92.                        throw ex;

  93.                    }

  94.                }

  95.            });

  96.            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

  97.        }

  98.  

  99.        else if (mbd.isPrototype()) {

  100.            // It's a prototype -> create a new instance.

  101.            Object prototypeInstance = null;

  102.            try {

  103.                beforePrototypeCreation(beanName);

  104.                prototypeInstance = createBean(beanName, mbd, args);

  105.            }

  106.            finally {

  107.                afterPrototypeCreation(beanName);

  108.            }

  109.            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);

  110.        }

  111.  

  112.        // 若是建立的bean 不是單例也不是原型, 則根據聲明週期選擇實例化bean的方法

  113.        // 如 request session 等不一樣範圍的實例

  114.        else {

  115.            String scopeName = mbd.getScope();

  116.            final Scope scope = this.scopes.get(scopeName);

  117.            // 若是 scope 是空, 則拋異常

  118.            if (scope == null) {

  119.                throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");

  120.            }

  121.            // 不然

  122.            try {

  123.                // 獲取一個指定了scope的bean實例

  124.                Object scopedInstance = scope.get(beanName, new ObjectFactory() {

  125.                    public Object getObject() throws BeansException {

  126.                        beforePrototypeCreation(beanName);

  127.                        try {

  128.                            return createBean(beanName, mbd, args);

  129.                        }

  130.                        finally {

  131.                            afterPrototypeCreation(beanName);

  132.                        }

  133.                    }

  134.                });

  135.                bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);

  136.            }

  137.            catch (IllegalStateException ex) {

  138.                throw new BeanCreationException(beanName,

  139.                        "Scope '" + scopeName + "' is not active for the current thread; " +

  140.                        "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",

  141.                        ex);

  142.            }

  143.        }

  144.    }

  145.  

  146.    // Check if required type matches the type of the actual bean instance.

  147.    // 檢查是否須要類型檢測

  148.    if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {

  149.        throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());

  150.    }

  151.    return (T) bean;

  152. }

總結如下它都作了什麼事情:

一、根據傳來的 bean的 name(有多是別名)來獲取真正的 bean名稱: beanName

二、根據 beanName獲取單例實例,若是有直接獲取到 bean實例並返回,DI完成。

三、若是根據 beanName沒有得到到單例實例:

3.1 判斷是否是原型實例,若是是,則拋出建立失敗異常,若是不是,下一步。

3.2 檢查 BeanDefinition 是否在當前的容器中,若是不在那可能在父類容器中,因此委託父類容器查找,若是尚未,則再上一級容器...遞歸查找。

3.3 檢查這個實例是不是爲了類型檢查而獲取,而不是用來使用,若是是,標記這個bean已經被建立,若是不是,下一步。

3.4 根據 beanName獲取 父類的BeanDefinition,並檢查該對象類類型,好比不能是抽象類等。

3.5 根據 beanName獲取全部該 bean依賴的 Bean集合,若是該集合有值,則遍歷DI(遞歸調用 getBean())該 bean集合裏的bean,並把bean註冊給當前的bean(維護了一個 map來存放關係)。

3.6 若是3.4中獲取的 BeanDefinition是單例,則根據該單例對象和 beanName和 args建立一個實例對象;不然,判斷 BeanDefinition是不是原型,若是是則根據 beanName,該對象, args建立一個實例;不然拿到3.4獲取的 BeanDefinition對象的生命週期 Scope,而後根據 scope來建立實例對象,參數 (beanName,bd,args)

  1. 3.7 檢查是否須要類型檢測

  2.  

  3. 3.8 返回`3.1-3.7 `生成的實例。

而後咱們再看看 createBean()方法的實現。
  1.    protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)

  2.            throws BeanCreationException;

3. AbstractAutowireCapableBeanFactory.java

  1. // 建立bean 實例

  2. @Override

  3. protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)

  4.        throws BeanCreationException {

  5.  

  6.    if (logger.isDebugEnabled()) {

  7.        logger.debug("Creating instance of bean '" + beanName + "'");

  8.    }

  9.    // Make sure bean class is actually resolved at this point.

  10.    // 解析和肯定 bean 能夠實例化

  11.    resolveBeanClass(mbd, beanName);

  12.  

  13.    // Prepare method overrides.

  14.    // 準備方法覆蓋

  15.    try {

  16.        mbd.prepareMethodOverrides();

  17.    }

  18.    catch (BeanDefinitionValidationException ex) {

  19.        throw new BeanDefinitionStoreException(mbd.getResourceDescription(),

  20.                beanName, "Validation of method overrides failed", ex);

  21.    }

  22.  

  23.    try {

  24.        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.

  25.        // 給 Bean處理器 一個機會, 返回一個目標bean實例

  26.        Object bean = resolveBeforeInstantiation(beanName, mbd);

  27.        if (bean != null) {

  28.            return bean;

  29.        }

  30.    }

  31.    catch (Throwable ex) {

  32.        throw new BeanCreationException(mbd.getResourceDescription(), beanName,

  33.                "BeanPostProcessor before instantiation of bean failed", ex);

  34.    }

  35.  

  36.    Object beanInstance = doCreateBean(beanName, mbd, args);

  37.    if (logger.isDebugEnabled()) {

  38.        logger.debug("Finished creating instance of bean '" + beanName + "'");

  39.    }

  40.    return beanInstance;

  41. }

總結如下它都作了什麼:

  1. 肯定 beanName和 RootBeanDefinition能夠被實例化。

  2. 執行方法覆蓋

  3. 看 BeanPostProcessors可否再解析以前獲取到bean,若是能則直接返回,不然下一步。

  4. 調用 doCreateBean()方法,獲取 bean實例.

doCreateBean()方法也是該類中的。

  1. // 真正建立bean實例

  2. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {

  3.    // Instantiat|e the bean.

  4.    // 封裝bean

  5.    BeanWrapper instanceWrapper = null;

  6.    if (mbd.isSingleton()) {

  7.        // 若是是單例模式的bean,從容器中獲取同名bean

  8.        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);

  9.    }

  10.    // 若是沒有同名bean, 則建立bean實例

  11.    if (instanceWrapper == null) {

  12.        instanceWrapper = createBeanInstance(beanName, mbd, args);

  13.    }

  14.    // 若是有同名bean, 則獲取到封裝實例

  15.    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);

  16.    // 獲取實例化對象類型

  17.    Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

  18.  

  19.    // Allow post-processors to modify the merged bean definition.

  20.    // 調用後置處理器

  21.    synchronized (mbd.postProcessingLock) {

  22.        if (!mbd.postProcessed) {

  23.            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

  24.            mbd.postProcessed = true;

  25.        }

  26.    }

  27.  

  28.    // Eagerly cache singletons to be able to resolve circular references

  29.    // even when triggered by lifecycle interfaces like BeanFactoryAware.

  30.    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&

  31.            isSingletonCurrentlyInCreation(beanName));

  32.    if (earlySingletonExposure) {

  33.        if (logger.isDebugEnabled()) {

  34.            logger.debug("Eagerly caching bean '" + beanName +

  35.                    "' to allow for resolving potential circular references");

  36.        }

  37.        addSingletonFactory(beanName, new ObjectFactory() {

  38.            public Object getObject() throws BeansException {

  39.                return getEarlyBeanReference(beanName, mbd, bean);

  40.            }

  41.        });

  42.    }

  43.  

  44.    // Initialize the bean instance.

  45.    // bean對象初始化, 依賴注入開始,exposedObject就是完成後的bean

  46.    Object exposedObject = bean;

  47.    try {

  48.        // 將bean 實例封裝, 而且 bean 定義中配置的屬性值賦值給實例對象

  49.        populateBean(beanName, mbd, instanceWrapper);

  50.        // 初始化 bean對象

  51.        exposedObject = initializeBean(beanName, exposedObject, mbd);

  52.    }

  53.    catch (Throwable ex) {

  54.        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {

  55.            throw (BeanCreationException) ex;

  56.        }

  57.        else {

  58.            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);

  59.        }

  60.    }

  61.  

  62.    // 若是指定名稱bean已經註冊單例模式

  63.    if (earlySingletonExposure) {

  64.        Object earlySingletonReference = getSingleton(beanName, false);

  65.        if (earlySingletonReference != null) {

  66.            if (exposedObject == bean) {

  67.                // 若是兩個對象相等, bean初始化完成

  68.                exposedObject = earlySingletonReference;

  69.            }

  70.            // 若是不相等, 則找出當前bean的依賴bean

  71.            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {

  72.                String[] dependentBeans = getDependentBeans(beanName);

  73.                Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);

  74.                for (String dependentBean : dependentBeans) {

  75.                    // 檢查依賴bean (是否繼承接口,是不是父子關係。。)

  76.                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {

  77.                        actualDependentBeans.add(dependentBean);

  78.                    }

  79.                }

  80.                if (!actualDependentBeans.isEmpty()) {

  81.                    throw new BeanCurrentlyInCreationException(beanName,

  82.                            "Bean with name '" + beanName + "' has been injected into other beans [" +

  83.                            StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +

  84.                            "] in its raw version as part of a circular reference, but has eventually been " +

  85.                            "wrapped. This means that said other beans do not use the final version of the " +

  86.                            "bean. This is often the result of over-eager type matching - consider using " +

  87.                            "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");

  88.                }

  89.            }

  90.        }

  91.    }

  92.  

  93.    // Register bean as disposable.

  94.    // 註冊完成依賴注入的bean

  95.    try {

  96.        registerDisposableBeanIfNecessary(beanName, bean, mbd);

  97.    }

  98.    catch (BeanDefinitionValidationException ex) {

  99.        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);

  100.    }

  101.  

  102.    return exposedObject;

  103. }

一樣,總結如下它乾的事情:

  1. 根據 beanName獲取 beanWrapper對象。若是 beanWrapper對象是空,則調用 createBeanInstance()方法建立 bean實例。不然,下一步

  2. 經過 beanWrapper對象獲取bean實例和 class類型。

  3. 容許 postProcessors 調整組合 BeanDefinition

  4. 若是 RootBeanDefinition是單例而且容許循環引用而且 beanName正在進行單例建立,將 beanName添加到單例工廠。

  5. 調用 populateBean()方法給bean的屬性值賦值,而後初始化bean對象並返回建立的bean實例,若是拋異常,則下一步。

  6. 若是該 beanName對象已經註冊單例模式,則從單例中獲取,並判斷獲取到的bean實例( B)與 BeanWrapper中的bean實例( A)是同一個實例,若是是,則返回 A或者 B,若是不是,則遞歸找出它的依賴 bean

  7. 返回 1-6產生的 bean實例。

咱們首次獲取bean實例的時候,bean工廠是確定沒有的,因此咱們首次獲取到的BeanWrapper應該是空對象,可是它調用了 createBeanInstance()方法後,能夠看到spring是很肯定它能拿到對象,那麼咱們看看這個方法的實現。它仍然是這個類中的方法。

  1. protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {

  2.    // Make sure bean class is actually resolved at this point.

  3.    // 確保bean可實例化(不能是抽象類等)

  4.    Class beanClass = resolveBeanClass(mbd, beanName);

  5.  

  6.    // 若是這個bean 不是public 修飾符或者不被容許公共訪問, 拋出異常

  7.    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {

  8.        throw new BeanCreationException(mbd.getResourceDescription(), beanName,

  9.                "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());

  10.    }

  11.  

  12.    if (mbd.getFactoryMethodName() != null)  {

  13.        // 經過工廠方法實例化

  14.        return instantiateUsingFactoryMethod(beanName, mbd, args);

  15.    }

  16.  

  17.    // Shortcut when re-creating the same bean...

  18.    // 是否有構造器

  19.    if (mbd.resolvedConstructorOrFactoryMethod != null && args == null) {

  20.        if (mbd.constructorArgumentsResolved) {

  21.            return autowireConstructor(beanName, mbd, null, null);

  22.        }

  23.        else {

  24.            return instantiateBean(beanName, mbd);

  25.        }

  26.    }

  27.  

  28.    // Need to determine the constructor...

  29.    // 須要確認構造器

  30.    Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

  31.    if (ctors != null ||

  32.            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||

  33.            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {

  34.        // 自動裝配,調用匹配的構造方法進行實例化

  35.        return autowireConstructor(beanName, mbd, ctors, args);

  36.    }

  37.  

  38.    // No special handling: simply use no-arg constructor.

  39.    // 使用默認無參構造

  40.    return instantiateBean(beanName, mbd);

  41. }

這個類用來建立 Bean實例,而後返回 BeanWrapper對象。註釋寫的很詳細了。其中有個 instantiateBean()方法,當沒有參數和構造方法的時候,就會調用該方法來實例化bean。

  1. // 使用默認無參構造方法實例化bean

  2. protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {

  3.    try {

  4.        Object beanInstance;

  5.        final BeanFactory parent = this;

  6.        // 獲取JDK安全管理

  7.        if (System.getSecurityManager() != null) {

  8.            // 根據實例化策略實例化對象

  9.            beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {

  10.  

  11.                public Object run() {

  12.                    return getInstantiationStrategy().instantiate(mbd, beanName, parent);

  13.                }

  14.            }, getAccessControlContext());

  15.        }

  16.        else {

  17.            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

  18.        }

  19.        // 對實例化對象進行封裝

  20.        BeanWrapper bw = new BeanWrapperImpl(beanInstance);

  21.        initBeanWrapper(bw);

  22.        return bw;

  23.    }

  24.    catch (Throwable ex) {

  25.        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);

  26.    }

  27. }

這個方法是使用默認無參構造方法實例化bean的,它的核心代碼是 getInstantiationStrategy().instantiate(mbd,beanName,parent);,由於它,咱們能夠獲得一個bean實例對象,而後封裝成 BeanWrapper並返回。

4. SimpleInstantiationStrategy.java

用於BeanFactory的簡單對象實例化策略。不支持方法注入,儘管它提供了子類的hook來覆蓋以添加方法注入支持,例如經過重寫方法。

  1. // 使用初始化策略 實例化bean

  2. public Object instantiate(

  3.        RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {

  4.  

  5.    // Don't override the class with CGLIB if no overrides.

  6.    // 若是beanDefinition 中沒有方法覆蓋, 就用jdk,不然用cglib

  7.    if (beanDefinition.getMethodOverrides().isEmpty()) {

  8.        // 獲取對象的構造方法和工廠方法

  9.        Constructor constructorToUse = (Constructor) beanDefinition.resolvedConstructorOrFactoryMethod;

  10.  

  11.        if (constructorToUse == null) {

  12.            // 若是 沒有構造方法和工廠方法, 使用JDK反射, 判斷實例化的bean是否是接口

  13.            final Class clazz = beanDefinition.getBeanClass();

  14.            if (clazz.isInterface()) {

  15.                throw new BeanInstantiationException(clazz, "Specified class is an interface");

  16.            }

  17.            try {

  18.                if (System.getSecurityManager() != null) {

  19.                    // 使用反射獲取bean構造方法

  20.                    constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {

  21.                        public Constructor run() throws Exception {

  22.                            return clazz.getDeclaredConstructor((Class[]) null);

  23.                        }

  24.                    });

  25.                } else {

  26.                    constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);

  27.                }

  28.                beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;

  29.            }

  30.            catch (Exception ex) {

  31.                throw new BeanInstantiationException(clazz, "No default constructor found", ex);

  32.            }

  33.        }

  34.        // 使用beanUtils實例化   構造方法.newInstance(arg) 來實例化

  35.        return BeanUtils.instantiateClass(constructorToUse);

  36.    }

  37.    else {

  38.        //若是 有覆蓋或者重寫, 則用CGLIB來實例化對象

  39.        // Must generate CGLIB subclass.

  40.        return instantiateWithMethodInjection(beanDefinition, beanName, owner);

  41.    }

  42. }

總結它的步驟:

  1. 若是BeanDefinition的覆蓋方法不爲空,則交給CGLIB來實例化對象,不然獲取構造方法和工廠方法,下一步。

  2. 若是沒有構造方法和工廠方法,則使用JDK反射,判斷實例化的bean是否是接口,若是是,拋出異常,若是不是,則使用反射來獲取bean的構造方法,最後,用 構造器.newInstance()的方法( BeanUtils.instantiateClass()方法底層實現)來實例化並返回。

那cglib是如何實例化呢,咱們來看下 instantiateWithMethodInjection(beanDefinition,beanName,owner);方法源碼:

  1. @Override

  2. protected Object instantiateWithMethodInjection(

  3.        RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {

  4.  

  5.    // Must generate CGLIB subclass.

  6.    return new CglibSubclassCreator(beanDefinition, owner).instantiate(null, null);

  7. }

而後再跟進 CglibSubclassCreator(beanDefinition,owner).instantiate(null,null);方法:

  1. // 使用cglib 來進行bean實例化

  2. public Object instantiate(Constructor ctor, Object[] args) {

  3.    // cglib

  4.    Enhancer enhancer = new Enhancer();

  5.    // bean自己做爲基類

  6.    enhancer.setSuperclass(this.beanDefinition.getBeanClass());

  7.    enhancer.setCallbackFilter(new CallbackFilterImpl());

  8.    enhancer.setCallbacks(new Callback[] {

  9.            NoOp.INSTANCE,

  10.            new LookupOverrideMethodInterceptor(),

  11.            new ReplaceOverrideMethodInterceptor()

  12.    });

  13.  

  14.    // 生成實例對象

  15.    return (ctor == null) ?

  16.            enhancer.create() :

  17.            enhancer.create(ctor.getParameterTypes(), args);

  18. }

從上面代碼能夠看到,這就是CGLIB動態代理中建立代理的過程代碼,不熟悉的能夠往前翻 完全搞懂動態代理章節的內容。

好了,到了這裏,Spring就完成了bean實例的建立,可是此時就能拿着這個實例去使用嗎,顯然是不能夠,由於屬性尚未被賦入,下一章再繼續介紹如何將屬性依賴關係注入到Bean實例對象。

相關文章
相關標籤/搜索