spring的finishBeanFactoryInitialization方法分析

spring源碼版本5.0.5

概述

        該方法會實例化所有剩餘的非懶加載單例 bean。除了一些內部的 bean、實現了 BeanFactoryPostProcessor 接口的 bean、實現了 BeanPostProcessor 接口的 bean,其他的非懶加載單例 bean 都會在這個方法中被實例化,並且 BeanPostProcessor 的觸發也是在這個方法中。

分析

        跟蹤到AbstractApplicationContext.refresh()方法,找到代碼finishBeanFactoryInitialization(beanFactory)查看實現。

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Initialize conversion service for this context.
        // 1.初始化此上下文的轉換服務
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        // Register a default embedded value resolver if no bean post-processor
        // (such as a PropertyPlaceholderConfigurer bean) registered any before:
        // at this point, primarily for resolution in annotation attribute values.
        // 2.如果beanFactory之前沒有註冊嵌入值解析器,則註冊默認的嵌入值解析器:主要用於註解屬性值的解析
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        // 3.初始化LoadTimeWeaverAware Bean實例對象
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

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

        // Allow for caching all bean definition metadata, not expecting further changes.
        // 4.凍結所有bean定義,註冊的bean定義不會被修改或進一步後處理,因爲馬上要創建 Bean 實例對象了
        beanFactory.freezeConfiguration();

        // Instantiate all remaining (non-lazy-init) singletons.
        // 5.實例化所有剩餘(非懶加載)單例對象
        beanFactory.preInstantiateSingletons();
    }

繼續跟蹤到DefaultListableBeanFactory#preInstantiateSingletons

    public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Pre-instantiating singletons in " + this);
        }

        // Iterate over a copy to allow for init methods which in turn register new bean definitions.
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        //遍歷beanNames,觸發所有非懶加載單例bean的初始化
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //Bean實例:不是抽象類 && 是單例 && 不是懶加載
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
              //判斷beanName對應的bean是否爲FactoryBean
                if (isFactoryBean(beanName)) {
                  //通過getBean(&beanName)拿到的是FactoryBean本身;通過getBean(beanName)拿到的是FactoryBean創建的Bean實例
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        //判斷這個FactoryBean是否希望急切的初始化
                        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對應的bean不是FactoryBean,只是普通Bean,通過beanName獲取bean實例
                    getBean(beanName);
                }
            }
        }

        ......
    }

要理解FactoryBean和Bean的區別

        一般情況下,Spring 通過反射機制利用 bean 的  class 屬性指定實現類來實例化 bean。而 FactoryBean 是一種特殊的 bean,它是個工廠 bean,可以自己創建 bean 實例,如果一個類實現了 FactoryBean 接口,則該類可以自己定義創建實例對象的方法,只需要實現它的 getObject() 方法。

注:很多中間件都利用 FactoryBean 來進行擴展。

引入了幾個重要的緩存:

  • mergedBeanDefinitions 緩存:beanName -> 合併的 bean 定義。
  • beanDefinitionMap 緩存:beanName -> BeanDefinition。
  • singletonObjects 緩存:beanName -> 單例 bean 對象。
  • earlySingletonObjects 緩存:beanName -> 單例 bean 對象,該緩存存放的是早期單例 bean 對象,可以理解成還未進行屬性填充、初始化。
  • singletonFactories 緩存:beanName -> ObjectFactory。
  • singletonsCurrentlyInCreation 緩存:當前正在創建單例 bean 對象的 beanName 集合。

繼承跟蹤到AbstractBeanFactory#doGetBean創建bean

    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        //解析beanName,主要是解析別名、去掉FactoryBean的前綴“&”
        final String beanName = transformedBeanName(name);
        Object bean;

        // Eagerly check singleton cache for manually registered singletons.
        //嘗試從緩存中獲取beanName對應的實例,通過緩存解決循環依賴問題
        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 + "'");
                }
            }
            //返回beanName對應的實例對象(主要用於FactoryBean的特殊處理,普通Bean會直接返回sharedInstance本身)
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            // scope爲prototype非單例的循環依賴校驗:如果beanName已經正在創建Bean實例中,而此時我們又要再一次創建beanName的實例,則代表出現了循環依賴,需要拋出異常。
            // 例子:如果存在A中有B的屬性,B中有A的屬性,那麼當依賴注入的時候,就會產生當A還未創建完的時候因爲對於B的創建再次返回創建A,造成循環依賴
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            BeanFactory parentBeanFactory = getParentBeanFactory();
            //如果parentBeanFactory存在,並且beanName在當前BeanFactory不存在Bean定義,則嘗試從parentBeanFactory中獲取bean實例
            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);
                }
            }

            if (!typeCheckOnly) {
              //如果不是僅僅做類型檢測,而是創建bean實例,這裏要將beanName放到alreadyCreated緩存
                markBeanAsCreated(beanName);
            }

            try {
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.
                //拿到當前bean依賴的bean名稱集合,在實例化自己之前,需要先實例化自己依賴的bean,如使用@DependsOn
                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);
                        }
                    }
                }

                // Create bean instance.
                if (mbd.isSingleton()) {
                   //scope爲singleton的bean創建(新建了一個ObjectFactory,並且重寫了getObject方法,在裏面創建bean
                    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;
                        }
                    });
                    //返回beanName對應的實例對象
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                //其它非單例的情況,暫不分析
                ......
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }

        ......
        return (T) bean;
    }

查看DefaultSingletonBeanRegistry#getSingleton

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            //首先檢查beanName對應的bean實例是否在緩存中存在,如果已經存在,則直接返回
            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放入正準備創建的一個Set中singletonsCurrentlyInCreation,如果重複會報異常
                //如果存在構造器循環依賴的時候(A(B b),B(C c),C(A a)),會在這點報出異常
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    //執行singletonFactory的getObject方法獲取bean實例,就是執行傳入方法createBean
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                
                ......
                
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    //創建單例後的操作,在singletonsCurrentlyInCreation中移除
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

 

 

繼承跟蹤AbstractAutowireCapableBeanFactory#createBean

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

        ......
        
        try {
            //驗證及準備覆蓋的方法(對override屬性進行標記及驗證)
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            //實例化前的處理,如果有實現InstantiationAwareBeanPostProcessor的BeanPostProcessor可以直接返回真正的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 {
            //創建Bean實例(一般真正創建Bean的方法)
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        ......
    }

實例化前的處理,給 InstantiationAwareBeanPostProcessor 一個機會返回代理對象來替代真正的 bean 實例,從而跳過 Spring 默認的實例化過程,達到“短路”效果。會執行 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法,該方法可以返回 bean 實例的代理,從而跳過 Spring 默認的實例化過程。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章