Spring IOC實現原理筆記(三) -- 加載bean實例

本篇分析Spring如何加載bean的實例,
從ClassPathXmlApplicationContext的getBean開始分析
ClassPathXmlApplicationContext

//抽象方法
Object getBean(String var1) throws BeansException;

public Object getBean(String name) throws BeansException {
    this.assertBeanFactoryActive();
    return this.getBeanFactory().getBean(name);
}

會進入BeanFactory接口的getBean,根據繼承圖找到AbstractApplicationContext的getBean方法

上篇文章Spring IOC實現原理筆記(二) – 加載XML配置提過,ClassPathXmlApplicationContext中的BeanFactory成員實際是DefaultListableBeanFactory

DefaultListableBeanFactory

public Object getBean(String name) throws BeansException {
    return this.doGetBean(name, (Class)null, (Object[])null, false);
}

protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
    final String beanName = this.transformedBeanName(name);
    //【標記1】嘗試獲取
    Object sharedInstance = this.getSingleton(beanName);//
    Object bean;
    if(sharedInstance != null && args == null) {
        ...
//返回對應的實例,有時候存在諸如BeanFactory的情況並不是直接返回實例本身   
//而是返回指定方法返回的實例
        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
//原型模式(Prototype)下存在循環依賴,不能解決(因爲原型模式是直接創建新的實例的)
        if(this.isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        ...如果父BeanFactory不爲空,並且當前沒有相應bean的  
BeanDefinition,那就交由父BeanFactory加載bean,並返回。

        if(!typeCheckOnly) {
            this.markBeanAsCreated(beanName);//標誌當前bean已經創建
        }
        try {
//將存儲XML配置文件的GenericBeanDefinition轉換爲RootBeanDefinition
            final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
            this.checkMergedBeanDefinition(mbd, beanName, args);
            String[] dependsOn = mbd.getDependsOn();
            String[] var11;
            if(dependsOn != null) {
                for(String dependsOnBean:dependsOn) {
                    String dependsOnBean = var11[var13];
                    if(this.isDependent(beanName, dependsOnBean)) {
                        ...說明有循環依賴,要報異常(構造方法注入循環依賴)
                    }
        //這裏記錄要創建的依賴的bean,用於循環依賴檢測
                    this.registerDependentBean(dependsOnBean, beanName);
        //遞歸實例化依賴的bean
                    this.getBean(dependsOnBean);
                }
            }

            if(mbd.isSingleton()) {//單例模式
                //【標記2】
                sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
                    public Object getObject() throws BeansException {
                        try {
                            //【標記3】
                            return this.createBean(beanName, mbd, args);//真正創建實例
                        } catch (BeansException var2) {
                            this.destroySingleton(beanName);
                            throw var2;
                        }
                    }
                });
                bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            } else ...省略其他模式
        } catch (BeansException var23) {
            this.cleanupAfterBeanCreationFailure(beanName);
            throw var23;
        }
    }
    if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
//對應類型的轉換
            return this.getTypeConverter().convertIfNecessary(bean, requiredType);
            ...
    } else {
        return bean;
    }
}

獲取bean實例時,首先嚐試獲取單例(對應上面【標記1】)

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//嘗試從緩存池中獲取
    Object singletonObject = this.singletonObjects.get(beanName);
    if(singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
//獲取不到,但正在創建
        synchronized(this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
//如果此bean不是正在加載且允許提前引用
            if(singletonObject == null && allowEarlyReference) {
    //當某些方法需要提前初始化的時候,會調用addSingletonFactory方法,  
    //將對應的ObjectFactory初始化策略存儲在singletonFactories
                ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                if(singletonFactory != null) {
        //調用預設定的getObject方法
                    singletonObject = singletonFactory.getObject();
        //記錄緩存中
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject != NULL_OBJECT?singletonObject:null;
}

獲取單例bean:(對應【標記2】)

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    ...
    synchronized(this.singletonObjects) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if(singletonObject == null) {
...
//把beanName放入singletonsCurrentlyInCreation
            this.beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = this.suppressedExceptions == null;
            if(recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet();
            }
            try {
    //調用工廠的getObject方法獲取實例
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            } catch ...
            } finally {
                ...
    //把beanName從singletonsCurrentlyInCreation移除
                this.afterSingletonCreation(beanName);
            }
            if(newSingleton) {
                this.addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject != NULL_OBJECT?singletonObject:null;
    }
}
//把beanName緩存到singletonsCurrentlyInCreation,對應的isSingletonCurrentlyInCreation方法會返回true
protected void beforeSingletonCreation(String beanName) {
    if(!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
    }
}
//把beanName從singletonsCurrentlyInCreation移除
protected void afterSingletonCreation(String beanName) {
    if(!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}

ObjectFactory工廠的getObject方法實現調用的是createBean方法(對應【標記3】)

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    ...
    RootBeanDefinition mbdToUse = mbd;
    Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
    if(resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }
    ...
    //驗證及準備覆蓋的方法
        mbdToUse.prepareMethodOverrides();
    ...
    Object beanInstance;
    ...
//給BeanPostProcessors(需要是InstantiationAwareBeanPostProcessor的實例)機會返回代理來代替真正的實例(AOP實現就用這)
        beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
        if(beanInstance != null) {
            return beanInstance;
        }
    ...
    //真正創建bean實例
    beanInstance = this.doCreateBean(beanName, mbdToUse, args);
    ...
    return beanInstance;
}

真正創建bean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {
    BeanWrapper instanceWrapper = null;
    if(mbd.isSingleton()) {
        instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
    }
    if(instanceWrapper == null) {
//【標記4】根據指定bean使用對應的策略創建新的實例,如工廠方法,構造函數自動注入,簡單初始化
        instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null;
    Class<?> beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null;
    synchronized(mbd.postProcessingLock) {
        if(!mbd.postProcessed) {
//應用MergedBeanDefinitionPostProcessor
            this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            mbd.postProcessed = true;
        }
    }
//是否需要提早曝光:單例&允許循環依賴&當前bean正在創建中,檢查循環依賴
    boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
    if(earlySingletonExposure) {
        ...
//爲避免後期循環依賴,可以在bean初始化完成前將創建實例的ObjectFactory工廠加入工廠
        this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
            public Object getObject() throws BeansException {
//對bean再一次依賴應用,主要應用SmartInstantiationAwareBeanPostProcessor
//AOP就是在這裏將advice動態織入bean中,沒有就直接返回bean,不做處理
                return this.getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }
    Object exposedObject = bean;
    try {
//【標記5】對bean進行填充,將各個屬性值注入,其中可能存在依賴於其他bean的屬性,則會遞歸初始依賴的bean
        this.populateBean(beanName, mbd, instanceWrapper);
        if(exposedObject != null) {
//【標記6】調用初始化方法,如init-method,InitializingBean的afterPropertiesSet
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        }
    } catch...
    if(earlySingletonExposure) {
        Object earlySingletonReference = this.getSingleton(beanName, false);
//只有在檢測到有循環依賴的情況下才會不會空
        if(earlySingletonReference != null) {
            if(exposedObject == bean) {
    //沒有在初始化方法中被改變(即沒有被增強)
                exposedObject = earlySingletonReference;
            } else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                String[] dependentBeans = this.getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                for(String dependentBean:dependentBeans) {
        //檢測依賴,bean實例化後,其依賴的bean也需要被實例化
                    if(!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if(!actualDependentBeans.isEmpty()) {
                    ...存在循環依賴
                }
            }
        }
    }

    try {
        //根據scope註冊bean
        this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
        return exposedObject;
    } catch ...
}

單例的循環依賴解決:如果是在構造函數循環依賴那解決不了;如果是通過setter方法的循環依賴,那會調addSingletonFactory加入一個ObjectFactory,其getObject實現會返回一個實例引用來解決循環依賴

根據指定bean使用對應的策略創建新的實例(對應【標記4】)

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
    Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
    if(beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        ...非公開類
    } else if(mbd.getFactoryMethodName() != null) {
//如果工廠方法不爲空則使用工廠方法初始化策略
        return this.instantiateUsingFactoryMethod(beanName, mbd, args);
    } else {
        boolean resolved = false;
        boolean autowireNecessary = false;
        if(args == null) {
            synchronized(mbd.constructorArgumentLock) {
    //一個類有多個構造函數,每個構造函數都有不同的參數,所以調用前根據參數鎖定構造函數或對應的工廠方法
                if(mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
//如果已經解析過則使用解析好的構造函數
        if(resolved) {
//autowireNecessary爲true則用構造函數自動注入,否則使用默認構造函數構造
            return autowireNecessary?this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null):this.instantiateBean(beanName, mbd);
        } else {
//根據參數解析構造函數
            Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
//ctors爲空就用默認構造函數,否則使用用構造函數自動注入
            return ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)?this.instantiateBean(beanName, mbd):this.autowireConstructor(beanName, mbd, ctors, args);
        }
    }
}

根據參數解析構造函數邏輯很複雜,因爲有很多不確定性;而使用默認構造方法實例化則會分兩種情況:第一種,beanDefinition的getMethodOverrides方法返回空(即沒有使用replace或lookup配置),那就直接使用反射。第二種,使用CGlib進行動態代理,覆蓋或動態替換方法

上面實例化的bean,接着就是對bean進行屬性填充,看populateBean方法(對用【標記5】)

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    PropertyValues pvs = mbd.getPropertyValues();
    if(bw == null) {
        if(!((PropertyValues)pvs).isEmpty()) {
            ...空對象不能填充屬性
        }
    } else {
//給InstantiationAwareBeanPostProcessors最後一次機會在屬性設置前改變bean
        boolean continueWithPropertyPopulation = true;
        if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
            Iterator it = this.getBeanPostProcessors().iterator();
            while(it.hasNext()) {
                BeanPostProcessor bp = (BeanPostProcessor)it.next();
                if(bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                    if(!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }
//continueWithPropertyPopulation爲true,說明InstantiationAwareBeanPostProcessors沒有中斷屬性注入
        if(continueWithPropertyPopulation) {
            if(mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
                MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
    //根據名稱自動注入
                if(mbd.getResolvedAutowireMode() == 1) {
                    this.autowireByName(beanName, mbd, bw, newPvs);
                }
    //根據類型自動注入
                if(mbd.getResolvedAutowireMode() == 2) {
                    this.autowireByType(beanName, mbd, bw, newPvs);
                }
                pvs = newPvs;
            }
            boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
//依賴檢查
            boolean needsDepCheck = mbd.getDependencyCheck() != 0;
            if(hasInstAwareBpps || needsDepCheck) {
//調用InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法
                PropertyDescriptor[] filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                if(hasInstAwareBpps) {
                    Iterator it = this.getBeanPostProcessors().iterator();
                    while(it.hasNext()) {
                        BeanPostProcessor bp = (BeanPostProcessor)it.next();
                        if(bp instanceof InstantiationAwareBeanPostProcessor) {
                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                            pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                            if(pvs == null) {
                                return;
                            }
                        }
                    }
                }
                if(needsDepCheck) {
                    this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
                }
            }
//將屬性應用到bean中
            this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
        }
    }
}

填充好bean的屬性後,會調用initializeBean方法會對各種aware等接口進行調用(對應【標記6】)

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    ...
    this.invokeAwareMethods(beanName, bean);
    Object wrappedBean = bean;
    if(mbd == null || !mbd.isSynthetic()) {
//調用BeanPostProcessors的postProcessBeforeInitialization
        wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
    }
    try {
//調用init-method,InitializingBean的afterPropertiesSet
        this.invokeInitMethods(beanName, wrappedBean, mbd);
    } catch...
    if(mbd == null || !mbd.isSynthetic()) {
//調用BeanPostProcessors的postProcessAfterInitialization
        wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

Spring IOC實現原理筆記(一)這篇中的例子輸出結果可以在從上面裏驗證了

大致總結bean實例的加載流程:

• 嘗試從單例緩存池中取,成功的話返回進行實際需要的實例(如在beanName前加&可以得到該bean的beanFactory)
• 單例緩存池取不到則進行實例化,需要判斷能否解決循環引用,不同的scope不同地生命週期。
• 進行實例化前,如果工廠方法不爲空則使用工廠方法初始化策略;否則可以通過InstantiationAwareBeanPostProcessor來實例化(AOP藉此實現),如果InstantiationAwareBeanPostProcessor返回實例化對象不爲空那就直接返回。
• InstantiationAwareBeanPostProcessor沒返回實例,則繼續進行bean實例操作,解析構造函數,用其進行反射實例化或CGlib代理實例化
• 實例化後,對實例進行屬性填充,填充前還會最後一次交由InstantiationAwareBeanPostProcessor決定是否繼續填充,
• 填充完屬性,還會讓InstantiationAwareBeanPostProcessor進行屬性檢驗,接着就進行對各種Aware接口,init-method等進行調用
• 最後註冊DisposeableBean,用戶可通過配置屬性destroy-method方法後之策後處理器DestructAwareBeanPostProcessor來統一處理bean的銷燬方法

參考:

Spring源碼(4.2.2.RELEASE)

《Spring源碼深度解析》

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