springboot筆記-3-.實例化bean


前言

  前面幾章spring已經把需要的注冊的bean的信息已經全部加載到了BeanFactory中了,那么之后要做的事兒當然就是進行實例化了,當然了可能有人會問為何不在加載到bean信息的時候直接進行實例化呢,這不還需要依賴注入嘛,當然是要所有的都加載完了才能實例化。ApplicationContext相對於BeanFactory來說,早期的BeanFactory受制於硬件配置,所以在我們需要某個bean的時候才會進行實例化。而ApplicationContext則會在一開始就將所有的注冊的Bean(標記懶加載的,或者非單例加載除外)全部進行實例化。本文則主要介紹spring如何實例化bean,並且Bean的生命周期也會穿插其中。

 

這兒先放一張加載的大致流程圖

  從圖中可以看到加正式加載的過程並不多,實例化->放入提前暴露容器->賦值完成后其實就算完成實例化了,但spring在其中穿插了 很多的BeanPostProcessor以及aware,同時也會根據所加載bean是否實現了InitializingBean接口來決定是否需要執行afterPropertiesSet方法。說明spring在實例化bean時給我們流下了足夠的擴展空間。

正文

  我們回到上下文的refresh方法中

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            ../代碼略

            try {
                postProcessBeanFactory(beanFactory);
                invokeBeanFactoryPostProcessors(beanFactory);

                // 注冊所有BeanPostProcessors
                registerBeanPostProcessors(beanFactory);

                ../代碼略

                //實例化bean
                finishBeanFactoryInitialization(beanFactory);
                ../代碼略
            }

            ../代碼略
        }
    }

  前面一篇我們成功的執行了invokeBeanFactoryPostProcessors方法,然后將所有的BeanFactoryPostProcessor后置方法執行了,然后也成功的將所有需要注冊到容器的bean的BeanDefination也收集到了BeanFactory中。本文則主要關注后面兩個方法。

  • registerBeanPostProcessors  按照一定順序注冊BeanPostProcessor
  • 實例化所有的bean  

  至於注冊BeanPostProcessor較為簡單,就是將系統所有的BeanPostProcessor按照順序,即我們之前也遇到的三級順序來添加,實現了PriorityOrdered為第一級,實現了Ordered為第二級,其他的為第三級。具體添加過程較為簡單所以代碼部分略過,我們直接看實例化bean的方法

 

1.finishBeanFactoryInitialization 實例化的入口

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 初始化一個ConversionService
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        // 初始化一個默認的EmbeddedValueResolver(如果系統沒有指定的話)
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // 實例化LoadTimeWeaverAware   getBean方法會觸發實例化
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // Stop using the temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(null);

        //實例化之前凍結配置
        beanFactory.freezeConfiguration();

        // 實例化所有非懶加載的實例  
        beanFactory.preInstantiateSingletons();
}

  這兒就是做了一些必要的提前設置。這兒我們進入beanFactory.preInstantiateSingletons方法,注意這兒的beanFactory一般為DefaultListableBeanFactory,本系列第二章初始化應用上下文有講到

 

2.preInstantiateSingletons

  顧名思義,看方法名就知道是實例化之前的一些准備,看代碼

 

  

@Override
    public void preInstantiateSingletons() throws BeansException {
        //打印下日志
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Pre-instantiating singletons in " + this);
        }

        //迭代spring找到的所有需要注冊的bean
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        //開始迭代
        for (String beanName : beanNames) {
            
            //獲取該bean對應的mergedBeanDefinition  
            //如果沒有則獲取其父類的MergedLocalBeanDefinition  
            //如果父類為空則創建RootBeanDefinition
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //如果不是抽象類   且是單例構造  非懶加載  則實例化
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //如果該bean是FactoryBean
                if (isFactoryBean(beanName)) {
                    //如果是FactoryBean則要判斷下其是否需要提早初始化
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {
                //非factoryBean      初始化
                    getBean(beanName);
                }
            }
        }

        // 如果為SmartInitializingSingleton類型  則執行下其初始化完成后的afterSingletonsInstantiated方法
        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();
                }
            }
        }
    }

  方法也就是獲取我們之前得到的beanDefinitionNames,然后挨個遍歷,如果其不為抽象類,且是單例加載,非延遲加載,那我們就對其進行實例化。然后根據beanName獲取其合並的BeanDefinition,也就是其BeanDefinition一直遞歸加上其父類的BeanDefinition,最終合並為一個RootBeanDefinition並返回,具體的這兒的分析可以查看這篇博客。https://blog.csdn.net/andy_zhang2007/article/details/86514320

  獲取到合並的beanDefinition后,檢查其是否滿足加載的條件。這兒可以看出springboot滿足初始化即加載的條件主要由兩:單例記載,非懶加載。

  然后會判斷當前迭代的bean是否是FactoryBean,如果是則進行特殊判斷處理下,這兒二者最終都會調用getBean方法來創建類。創建完成后如果該bean實現了SmartInitializingSingleton接口,則會執行下其afterSingletonsInstantiated方法。

  其getBean方法是主要的創建方法,其實看到這兒也能發現。ApplicationContext方法的初始即實例化最終也是循環調用的BeanFactory的getBean方法。

 

3.getBean

 

 

 

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
        
        //獲取beanName
        final String beanName = transformedBeanName(name);
        Object bean;

        // 找下是否已經創建過
        Object sharedInstance = getSingleton(beanName);
        //如果已經開始創建且參數為空就不再執行創建邏輯了
        //這兒創建中分為了兩種情況
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                //如果該類創建中,但還未創建完成
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                //已經創建完成
                else {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            //直接拿出來並返回
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        //這兒則是創建流程
        else {
            //重復聲明時有可能出現此問題
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            //查看父BeanFactory是否已經有了 如果有的話則返回父BeanFactory中的實例
            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 {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }
            //標記該bean已經在開始被實例化
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                //獲取合並BeanDefinition
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                //檢查下合並BeanDefinition  這兒主要檢查是否為抽象類
                checkMergedBeanDefinition(mbd, beanName, args);

                // 獲取該bean的構造函數的參數
                //如果該bean構造函數中依賴的參數中,有參數實例化也需要依賴該bean 那么直接報循環引用的錯誤
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        //如果沒有循環引用也直接先實例化其依賴
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // 如果為scope為sington  那么只創建一個
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                // 如果為scope為Prototype  那么每次都創建個新的
                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;
            }
        }

        // 如果有合適的Converter  那么執行下converter轉換器的操作 返回轉換后的實例
        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.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

 

  該方法內容較多,但可以分步看

  1. 判斷是否已經創建中並能獲取實例,如果可以就返回,否則下一步
  2. 判斷一下重復加載的問題,然后查看父BeanFactory是否有該類,如果有則使用父類的getBean返回,否則下一步
  3. 判斷下循環循環引用的問題,如果構造函數有參數,但不存在循環引用,則先實例化構造參數
  4. 最終根據bean的scope來確定不同的初始化方式
  5. 根據初始化完成后的bean來尋找是否有合適的converter,如果有則轉換后返回,否則直接返回

 

  這樣拆開看發現也就是spring很常規的一個判斷邏輯,由於不同scope只是創建的數量不一致,但是實例化bean是一致的,所以我們就直接看實例化singleton,也就是我們最常見的單例注冊。

 

4.單例化代碼的片段

  上面的代碼中,我們着重看下創建單例的代碼片段。

if (mbd.isSingleton()) {
    //獲取創建后的實例
    sharedInstance = getSingleton(beanName, () -> {
        try {
            //回調函數創建bean
            return createBean(beanName, mbd, args);
        }
        catch (BeansException ex) {
            //出現異常則將其銷毀
            destroySingleton(beanName);
            throw ex;
        }
    });
    //看當前的bean是一個普通的bean還是beanFactory 
    //如果是普通的bean直接返回
    //如果是factoryBean則返回其getObject方法的結果
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

  這兒可以看到通過getSingletom方法獲取bean,這個方法有個回調函數是用來創建bean的,可以得知具體創建bean的時機肯定是getSingleton中調用這個函數的時候。getSingletom則只是做了一些前后處理。那我們還是先看下回調函數中的createBean方法,畢竟這才是核心創建過程。

 

5.createBean

  

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

        //獲取該bean的合並BeanDefinition
        RootBeanDefinition mbdToUse = mbd;

        //查看當前RootBeanDefinition是否已經有resolveBeanClass  如果有的話直接clone一個beanDefinition
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        //檢查下所有的override方法
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // 執行所有實現了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
            // 這兒如果返回不為null  則就是自定義了返回的bean邏輯
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }

        try {
            //執行doCreateBean創建bean
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        ../代碼省略
}

  該方法內部照例做了一下准備,其中有個方法需要注意resolveBeforeInstantiation ,該方法會在實例化之前執行所有實現了InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法,如果返回值不為空則代表自定義了類實例化過程,這樣會直接返回bean而不會進行下面的所有操作

  然后執行doCreateBean創建實例對象。

 

6.doCreateBean

  

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

        // 實例化bean 如果factoryBeanInstance已經有了則將其remove掉
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            //創建實例
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        //檢查下創建出來的bean是否為null,例如我們從beanFactory中get為null  或者@Bean方法返回為null
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        // 執行所有實現了MergedBeanDefinitionPostProcessor接口的類的postProcessMergedBeanDefinition方法
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        //如果允許屬性值循環依賴,則將實例其放入一個singletonFactories緩存中,此時該類已經實例化但還未為屬性賦值
        //如果該類依賴的屬性值實例化時依賴該類,那么就可以從這個singletonFactories提前拿到還未賦值的屬性值實例
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        
        Object exposedObject = bean;
        try {
            // 為實例賦屬性值
            populateBean(beanName, mbd, instanceWrapper);
            //執行一些列初始化方法
            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) {
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName,
                                "Bean with name '" + beanName + "' has been injected into other beans [" +
                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                "] in its raw version as part of a circular reference, but has eventually been " +
                                "wrapped. This means that said other beans do not use the final version of the " +
                                "bean. This is often the result of over-eager type matching - consider using " +
                                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        // 如果bean是一次性的則將其注入一次性使用容器中
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

  該方法有幾個地方需要注意

  1. 實例化bean后檢查了該bean是否為null
  2. 執行了所有實現了實現了MergedBeanDefinitionPostProcessor接口的類的postProcessMergedBeanDefinition方法
  3. 如果出現了屬性值循環引用,且允許循環引用,那么會將實例化好但還未賦值的bean放入一個singletonFactories提前暴露容器中來解決屬性值循環引用
  4. 然后在為屬性賦值
  5. 然后執行初始化方法。

  我們則簡要分析下這幾個步驟

 

6.1createBeanInstance創建實例

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // 確保beanClass可以被實例化  例如其是否為public   
        Class<?> beanClass = resolveBeanClass(mbd, beanName);

        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        }
        //查看該類是否有定制的Supplier  如果有直接返回
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }
        //查看該類是否為@Bean方法初始化  如果是的話執行方法邏輯
        if (mbd.getFactoryMethodName() != null)  {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // Shortcut when re-creating the same bean...
        boolean resolved = false;
        boolean autowireNecessary = false;
        //如果初始化構造參數為null且能找到構造函數或者FactoryMethod(如果為factoryBean)
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    //查看其是否有@Autowired的參數
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {
            //如果有@Autowaired參數則執行這個autowireConstructor方法
            if (autowireNecessary) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            //如果沒有則執行instantiateBean方法
            else {
                return instantiateBean(beanName, mbd);
            }
        }

        //如果上面沒找到有效的構造函數  就從BeanPostProcessor中查找 然后執行返回
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        // No special handling: simply use no-arg constructor.
        return instantiateBean(beanName, mbd);
    }

  這兒步驟主要為   

     1.校驗是否能實例化 

     2.是否有定制的supplier,有則返回 

     3.是否為@Bean初始化,如果是則執行專門的實例化方法 

     4.如果傳入的構造參數為null,則根據自動注入的參數或者無參的方法來實例化。

     5.如果傳入的參數不為null  或者需要的參數里有不是自動注入的,那么根據BeanPostProcessor找到合適的構造函數並實例化

 

  這兒具體的對象創建過程由於篇幅就不講解了,可以根據各個方法進去仔細查看,不過大概能想到的應該就是根據傳入的參數反射創建實例,如果是@Bean方法創建的話應該是反射執行方法創建,如果需要代理的話則創建代理對象並返回。

 

6.2 applyMergedBeanDefinitionPostProcessors

  這也是springBean生命周期中的一個重要步驟

    protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof MergedBeanDefinitionPostProcessor) {
                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
            }
        }
    }

  該方法會執行所有的MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition方法。

 

6.3 處理屬性值循環引用addSingletonFactory

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

    這兒注意getEarlyBeanReference又會執行所有實現了SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法。

  此處其實就是利用了一個提前暴露的singletonFactories容器,將實例化但還未賦值的bean放置在其中,當循環引用的bean需要用到這個bean時就可以拿到還未賦值的bean。即可解決屬性值循環引用的問題。

    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        synchronized (this.singletonObjects) {
            if (!this.singletonObjects.containsKey(beanName)) {
                this.singletonFactories.put(beanName, singletonFactory); //singletonFactories 提前暴露的Factories容器
                this.earlySingletonObjects.remove(beanName);//singletonFactories 提前暴露的bean容器
                this.registeredSingletons.add(beanName);// 已注冊的單例容器
            }
        }
    }

  注意這兒有兩個容器都涉及到提前引用  ,區別是earlySingletonObjects 放置的實例化的bean   而singletonFactories 放置的是實例化的bean的包裝。之所以加個包裝是為了獲取提前暴露的引用時可以執行SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法。

    /** Cache of singleton factories: bean name --> ObjectFactory */
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    /** Cache of early singleton objects: bean name --> bean instance */
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

  具體的處理循環引用的邏輯文章最后會單獨說下,這兒注意get

 

6.4 為屬性賦值

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        //判空
        if (bw == null) {
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
                // Skip property population phase for null instance.
                return;
            }
        }

        //檢查下是否需要賦值 如果有某個InstantiationAwareBeanPostProcessor返回未false   那么就跳過賦值操作
        boolean continueWithPropertyPopulation = true;

        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }

        if (!continueWithPropertyPopulation) {
            return;
        }
        //獲取要賦值的屬性值
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
        
        //根據不同的來不同的注入
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

            // by name 例如@Resources
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }

            // by type 例如@Autowied
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }

            pvs = newPvs;
        }

        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
        //如果有對應的InstantiationAwareBeanPostProcessors則執行下其postProcessPropertyValues方法
        if (hasInstAwareBpps || needsDepCheck) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            if (hasInstAwareBpps) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            }
            if (needsDepCheck) {
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }

        if (pvs != null) {
            //將找到的屬性值賦上
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

  該方法檢查了下bean是否為空,和該bean是否需要賦值,然后找到了所有的InstantiationAwareBeanPostProcessor執行了下其postProcessPropertyValues (如果需要的話),最后將找到的值賦上。

 

6.5 初始化方法initializeBean

  bean實例化后會執行initializeBean方法。該方法會執行很多bean生命周期相關的方法。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            //1.執行所有實現了BeanNameAware的setBeanName方法
            //2.執行所有實現了BeanClassLoaderAware的setBeanClassLoader方法
            //3.執行所有實現了BeanFactoryAware的setBeanFactory方法
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //執行所有實現了BeanPostProcessor的postProcessBeforeInitialization方法
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            //如果該類實現了InitializingBean接口,則執行afterPropertiesSet方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            //執行所有實現了BeanPostProcessor的postProcessAfterInitialization方法
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

 

  該方法會執行很多的spring生命周期的方法,首先會執行一堆的aware前置方法。然后執行BeanPostProcessor的postProcessBeforeInitialization,然后如果該類實現了InitializingBean則執行afterPropertiesSet方法,最后執行BeanPostProcessor的postProcessAfterInitialization方法(該方法可以關注下,spring aop功能正是基於此實現的)。此時創建bean的工作已經基本完成了。

 

7.回到getSingleton

  上面所講的都是ObjectFactory的回調函數的實現內容,那么調用的時機,和調用的前后邏輯還需要我們了解一下。即本文第4節的getSingtone方法。

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            //看下singletonObject中是否已經有了 如果沒有進入創建
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                //校驗一下是否正在創建中,如果正在創建中直接拋異常
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
                
                //將當前bean加入singletonsCurrentlyInCreation容器
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    //執行回調函數的創建邏輯
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    // Has the singleton object implicitly appeared in the meantime ->
                    // if yes, proceed with it since the exception indicates that state.
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    //從singletonsCurrentlyInCreation容器中移除該bean
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    //將該bean添加到singletonObjects容器中  並從提前暴露的容器中移除
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

  可以看到該類中主要核查防止了重復加載,然后通過回調函數獲取我們創建的bean后,將其從提前暴露的容器中移除,然后放入BeanFactory的真正的bean容器中。此時一個bean就算被創建完成已經可以正式使用了。

  可以發現其中執行了很多的BeanPostProcessor和aware,這也是spring對bean的擴展性做的極高的一種體現。

  到此spring初始化一個bean已經成功了。有關spring的具體加載流程簡要圖已經在一開始給出,可以對照着查看。而且spring的bean的生命周期除了銷毀部分,其他的基本就是上述的內容。

 

后記

  關於spring解決屬性循環依賴的問題主要是如下的代碼。

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //如果未從singletonObjects獲取到就要嘗試從提前暴露的容器中拿
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                //從提前暴露的容器中拿singletonObject
                singletonObject = this.earlySingletonObjects.get(beanName);
                //如果也為空
                if (singletonObject == null && allowEarlyReference) {
                    //那么嘗試從提前暴露的包裝容器中拿
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        //如果包裝容器不為空,那么就拿到其引用 然后添加到提前暴露容器中 並從提前暴露的包裝容器中移除
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

  可以看到在獲取bean時如果沒獲取到會嘗試從提前暴露容器中獲取,如果還是獲取不到就從提前暴露的包裝容器中獲取。如果能獲取到就將其從包裝容器中移除,設置到容器中。

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM