成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring專題之Bean初始化源碼分析(2)

Pikachu / 3118人閱讀

摘要:前言這篇是專題初始化的第二篇,主要對(duì)初始化具體過程的源碼分析。上篇博客專題之初始化源碼分析中我們對(duì)如何開始初始化以及初始化的總體過程有了大致的了解,接下來就繼續(xù)上篇博客的結(jié)尾處開始來分析初始化的具體過程。

前言

這篇是Spring專題Bean初始化的第二篇,主要對(duì)bean初始化具體過程的源碼分析。上篇博客Spring專題之Bean初始化源碼分析(1)中我們對(duì)Spring如何開始初始化bean以及bena初始化的總體過程有了大致的了解,接下來就繼續(xù)上篇博客的結(jié)尾處開始來分析初始化bean的具體過程。

Bean初始化

上篇博客中我們知道了Spring在通過判斷bean定義是否是單例bean,是否是原型bena之后,最后都是調(diào)用了createBean方法去創(chuàng)建bean的,所以我們進(jìn)入該方法分析具體初始化過程。進(jìn)入方法后發(fā)現(xiàn)是該方法是AbstractBeanFactory的一個(gè)抽象方法,真正地調(diào)用是在子類AbstractAutowireCapableBeanFactory中重寫了。源碼如下:

    //創(chuàng)建Bean實(shí)例對(duì)象
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean "" + beanName + """);
        }
        RootBeanDefinition mbdToUse = mbd;

        //判斷需要?jiǎng)?chuàng)建的Bean是否可以實(shí)例化,即是否可以通過當(dāng)前的類加載器加載
        Class resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        //校驗(yàn)和準(zhǔn)備Bean中的方法覆蓋
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            //如果Bean配置了初始化前和初始化后的處理器,則試圖返回一個(gè)需要?jiǎng)?chuàng)建Bean的代理對(duì)象
            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 {
            //創(chuàng)建Bean的入口
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean "" + beanName + """);
            }
            return beanInstance;
        }
        catch (BeanCreationException ex) {
            throw ex;
        }
        catch (ImplicitlyAppearedSingletonException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }

這里我們有兩個(gè)地方需要了解的,第一個(gè)是resolveBeforeInstantiation方法,第二個(gè)是doCreateBean方法。之后我們重點(diǎn)分析doCreateBean方法,這里的resolveBeforeInstantiation方法主要是針對(duì)Bean如果配置了初始化前和初始化后的處理器,會(huì)試圖返回一個(gè)需要?jiǎng)?chuàng)建Bean的代理對(duì)象。那么現(xiàn)在我們開始進(jìn)入doCreateBean方法,源碼如下:

    //真正創(chuàng)建Bean的方法
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {

        //封裝被創(chuàng)建的Bean對(duì)象
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = instanceWrapper.getWrappedInstance();
        //獲取實(shí)例化對(duì)象的類型
        Class beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        //調(diào)用PostProcessor后置處理器
        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;
            }
        }

        //向容器中緩存單例模式的Bean對(duì)象,以防循環(huán)引用
        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");
            }
            //這里是一個(gè)匿名內(nèi)部類,為了防止循環(huán)引用,盡早持有對(duì)象的引用
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        //Bean對(duì)象的初始化,依賴注入在此觸發(fā)
        //這個(gè)exposedObject在初始化完成之后返回作為依賴注入完成后的Bean
        Object exposedObject = bean;
        try {
            //將Bean實(shí)例對(duì)象封裝,并且Bean定義中配置的屬性值賦值給實(shí)例對(duì)象
            populateBean(beanName, mbd, instanceWrapper);
            //初始化Bean對(duì)象
            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) {
            //獲取指定名稱的已注冊的單例模式Bean對(duì)象
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                //根據(jù)名稱獲取的已注冊的Bean和正在實(shí)例化的Bean是同一個(gè)
                if (exposedObject == bean) {
                    //當(dāng)前實(shí)例化的Bean初始化完成
                    exposedObject = earlySingletonReference;
                }
                //當(dāng)前Bean依賴其他Bean,并且當(dāng)發(fā)生循環(huán)引用時(shí)不允許新創(chuàng)建實(shí)例對(duì)象
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    //獲取當(dāng)前Bean所依賴的其他Bean
                    for (String dependentBean : dependentBeans) {
                        //對(duì)依賴Bean進(jìn)行類型檢查
                        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.");
                    }
                }
            }
        }

        // Register bean as disposable.
        //注冊完成依賴注入的Bean
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

這里有三個(gè)方法我們需要注意,第一個(gè)createBeanInstance方法,這是bean實(shí)例化的第一步,第二個(gè)是populateBean方法,這是bean依賴注入的地方,第三個(gè)是initializeBean,這是初始化bean的地方。

首先我們先看createBeanInstance方法,源碼如下:

    //創(chuàng)建Bean的實(shí)例對(duì)象
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // Make sure bean class is actually resolved at this point.
        //檢查確認(rèn)Bean是可實(shí)例化的
        Class beanClass = resolveBeanClass(mbd, beanName);

        //使用工廠方法對(duì)Bean進(jìn)行實(shí)例化
        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 instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }

        if (mbd.getFactoryMethodName() != null)  {
            //調(diào)用工廠方法實(shí)例化
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // Shortcut when re-creating the same bean...
        //使用容器的自動(dòng)裝配方法進(jìn)行實(shí)例化
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {
            if (autowireNecessary) {
                //配置了自動(dòng)裝配屬性,使用容器的自動(dòng)裝配實(shí)例化
                //容器的自動(dòng)裝配是根據(jù)參數(shù)類型匹配Bean的構(gòu)造方法
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                //使用默認(rèn)的無參構(gòu)造方法實(shí)例化
                return instantiateBean(beanName, mbd);
            }
        }

        // Need to determine the constructor...
        //使用Bean的構(gòu)造方法進(jìn)行實(shí)例化
        Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
            //使用容器的自動(dòng)裝配特性,調(diào)用匹配的構(gòu)造方法實(shí)例化
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        // No special handling: simply use no-arg constructor.
        //使用默認(rèn)的無參構(gòu)造方法實(shí)例化
        return instantiateBean(beanName, mbd);
    }

通過上述的源碼分析,我們知道Spring這里對(duì)bean實(shí)例化有幾種方式,分別是工廠方法實(shí)例化,容器自動(dòng)裝配以及使用默認(rèn)的無參構(gòu)造方法實(shí)例化。

然后我們在來看populateBean方法是如何進(jìn)行依賴注入的,源碼如下:

    //將Bean屬性設(shè)置到生成的實(shí)例對(duì)象上
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        //如果屬性存在但是需要注入的對(duì)象為空,則拋出異常。
        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;
            }
        }

        // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
        // state of the bean before properties are set. This can be used, for example,
        // to support styles of field injection.
        //使得InstantiationAwareBeanPostProcessors有機(jī)會(huì)在屬性注入之前修改bean的狀態(tài),例如支持一些屬性類型的注入。
        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;
        }
        //獲取容器在解析Bean定義資源時(shí)為BeanDefiniton中設(shè)置的屬性值
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

        //對(duì)依賴注入處理,首先處理autowiring自動(dòng)裝配的依賴注入
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

            // Add property values based on autowire by name if applicable.
            //根據(jù)Bean名稱進(jìn)行autowiring自動(dòng)裝配處理
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }

            // Add property values based on autowire by type if applicable.
            //根據(jù)Bean類型進(jìn)行autowiring自動(dòng)裝配處理
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }

            pvs = newPvs;
        }

        //對(duì)非autowiring的屬性進(jìn)行依賴注入處理
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

        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) {
            //對(duì)屬性進(jìn)行注入
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

這里有也有幾個(gè)方法需要注意,分別是autowireByName、autowireByType以及applyPropertyValues。
我們先來看下autowireByName方法,源碼如下:

    //根據(jù)名稱對(duì)屬性進(jìn)行自動(dòng)依賴注入
    protected void autowireByName(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

        //對(duì)Bean對(duì)象中非簡單屬性(不是簡單繼承的對(duì)象,如8中原始類型,字符串,URL等都是簡單屬性)進(jìn)行處理
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            //如果Spring IOC容器中包含指定名稱的Bean
            if (containsBean(propertyName)) {
                //調(diào)用getBean方法向IOC容器索取指定名稱的Bean實(shí)例,迭代觸發(fā)屬性的初始化和依賴注入
                Object bean = getBean(propertyName);
                //為指定名稱的屬性賦予屬性值
                pvs.add(propertyName, bean);
                //指定名稱屬性注冊依賴Bean名稱,進(jìn)行屬性依賴注入
                registerDependentBean(propertyName, beanName);
                if (logger.isDebugEnabled()) {
                    logger.debug("Added autowiring by name from bean name "" + beanName +
                            "" via property "" + propertyName + "" to bean named "" + propertyName + """);
                }
            }
            else {
                if (logger.isTraceEnabled()) {
                    logger.trace("Not autowiring property "" + propertyName + "" of bean "" + beanName +
                            "" by name: no matching bean found");
                }
            }
        }
    }

可以看到這里通過找到Bean中非簡單屬性的屬性,比如CharSequence類型、Number類型、Date類型、URL類型、URI類型、Locale類型、Class類型就會(huì)忽略,具體可見BeanUtils的isSimpleProperty方法,遍歷所有被找到的屬性,如果bean定義中包含了屬性名,那么先實(shí)例化該屬性名對(duì)應(yīng)的bean,注冊一下當(dāng)前bean的依賴bean。

然后我們看下根據(jù)類型自動(dòng)裝配autowireByType方法的實(shí)現(xiàn),源碼如下:

    //根據(jù)類型對(duì)屬性進(jìn)行自動(dòng)依賴注入
    protected void autowireByType(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

        //獲取用戶定義的類型轉(zhuǎn)換器
        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }

        //存放解析的要注入的屬性
        Set autowiredBeanNames = new LinkedHashSet<>(4);
        //對(duì)Bean對(duì)象中非簡單屬性(不是簡單繼承的對(duì)象,如8中原始類型,字符
        //URL等都是簡單屬性)進(jìn)行處理
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            try {
                //獲取指定屬性名稱的屬性描述器
                PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
                // Don"t try autowiring by type for type Object: never makes sense,
                // even if it technically is a unsatisfied, non-simple property.
                //不對(duì)Object類型的屬性進(jìn)行autowiring自動(dòng)依賴注入
                if (Object.class != pd.getPropertyType()) {
                    //獲取屬性的setter方法
                    MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                    // Do not allow eager init for type matching in case of a prioritized post-processor.
                    //檢查指定類型是否可以被轉(zhuǎn)換為目標(biāo)對(duì)象的類型
                    boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
                    //創(chuàng)建一個(gè)要被注入的依賴描述
                    DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                    //根據(jù)容器的Bean定義解析依賴關(guān)系,返回所有要被注入的Bean對(duì)象
                    Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
                    if (autowiredArgument != null) {
                        //為屬性賦值所引用的對(duì)象
                        pvs.add(propertyName, autowiredArgument);
                    }
                    for (String autowiredBeanName : autowiredBeanNames) {
                        //指定名稱屬性注冊依賴Bean名稱,進(jìn)行屬性依賴注入
                        registerDependentBean(autowiredBeanName, beanName);
                        if (logger.isDebugEnabled()) {
                            logger.debug("Autowiring by type from bean name "" + beanName + "" via property "" +
                                    propertyName + "" to bean named "" + autowiredBeanName + """);
                        }
                    }
                    //釋放已自動(dòng)注入的屬性
                    autowiredBeanNames.clear();
                }
            }
            catch (BeansException ex) {
                throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
            }
        }
    }

具體的解析過程主要看resolveDependency方法,這里感興趣的同學(xué)可以研究下具體過程。
最后我們來看下applyPropertyValues方法,源碼如下:

    //解析并注入依賴屬性的過程
    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if (pvs.isEmpty()) {
            return;
        }

        //封裝屬性值
        MutablePropertyValues mpvs = null;
        List original;

        if (System.getSecurityManager() != null) {
            if (bw instanceof BeanWrapperImpl) {
                //設(shè)置安全上下文,JDK安全機(jī)制
                ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
            }
        }

        if (pvs instanceof MutablePropertyValues) {
            mpvs = (MutablePropertyValues) pvs;
            //屬性值已經(jīng)轉(zhuǎn)換
            if (mpvs.isConverted()) {
                // Shortcut: use the pre-converted values as-is.
                try {
                    //為實(shí)例化對(duì)象設(shè)置屬性值
                    bw.setPropertyValues(mpvs);
                    return;
                }
                catch (BeansException ex) {
                    throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
                }
            }
            //獲取屬性值對(duì)象的原始類型值
            original = mpvs.getPropertyValueList();
        }
        else {
            original = Arrays.asList(pvs.getPropertyValues());
        }

        //獲取用戶自定義的類型轉(zhuǎn)換
        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }
        //創(chuàng)建一個(gè)Bean定義屬性值解析器,將Bean定義中的屬性值解析為Bean實(shí)例對(duì)象的實(shí)際值
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        // Create a deep copy, resolving any references for values.

        //為屬性的解析值創(chuàng)建一個(gè)拷貝,將拷貝的數(shù)據(jù)注入到實(shí)例對(duì)象中
        List deepCopy = new ArrayList<>(original.size());
        boolean resolveNecessary = false;
        for (PropertyValue pv : original) {
            //屬性值不需要轉(zhuǎn)換
            if (pv.isConverted()) {
                deepCopy.add(pv);
            }
            //屬性值需要轉(zhuǎn)換
            else {
                String propertyName = pv.getName();
                //原始的屬性值,即轉(zhuǎn)換之前的屬性值
                Object originalValue = pv.getValue();
                //轉(zhuǎn)換屬性值,例如將引用轉(zhuǎn)換為IOC容器中實(shí)例化對(duì)象引用
                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                //轉(zhuǎn)換之后的屬性值
                Object convertedValue = resolvedValue;
                //屬性值是否可以轉(zhuǎn)換
                boolean convertible = bw.isWritableProperty(propertyName) &&
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                if (convertible) {
                    //使用用戶自定義的類型轉(zhuǎn)換器轉(zhuǎn)換屬性值
                    convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
                }
                // Possibly store converted value in merged bean definition,
                // in order to avoid re-conversion for every created bean instance.
                //存儲(chǔ)轉(zhuǎn)換后的屬性值,避免每次屬性注入時(shí)的轉(zhuǎn)換工作
                if (resolvedValue == originalValue) {
                    if (convertible) {
                        //設(shè)置屬性轉(zhuǎn)換之后的值
                        pv.setConvertedValue(convertedValue);
                    }
                    deepCopy.add(pv);
                }
                //屬性是可轉(zhuǎn)換的,且屬性原始值是字符串類型,且屬性的原始類型值不是
                //動(dòng)態(tài)生成的字符串,且屬性的原始值不是集合或者數(shù)組類型
                else if (convertible && originalValue instanceof TypedStringValue &&
                        !((TypedStringValue) originalValue).isDynamic() &&
                        !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                    pv.setConvertedValue(convertedValue);
                    //重新封裝屬性的值
                    deepCopy.add(pv);
                }
                else {
                    resolveNecessary = true;
                    deepCopy.add(new PropertyValue(pv, convertedValue));
                }
            }
        }
        if (mpvs != null && !resolveNecessary) {
            //標(biāo)記屬性值已經(jīng)轉(zhuǎn)換過
            mpvs.setConverted();
        }

        // Set our (possibly massaged) deep copy.
        //進(jìn)行屬性依賴注入
        try {
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }

這里主要是對(duì)需要轉(zhuǎn)換的屬性進(jìn)行轉(zhuǎn)換然后進(jìn)行屬性值的依賴注入。

至此屬性的依賴注入分析結(jié)束,最后我們看下initializeBean方法是如何對(duì)bean進(jìn)行初始化操作的,其源碼如下:

    //初始容器創(chuàng)建的Bean實(shí)例對(duì)象,為其添加BeanPostProcessor后置處理器
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        //JDK的安全機(jī)制驗(yàn)證權(quán)限
        if (System.getSecurityManager() != null) {
            //實(shí)現(xiàn)PrivilegedAction接口的匿名內(nèi)部類
            AccessController.doPrivileged((PrivilegedAction) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            //為Bean實(shí)例對(duì)象包裝相關(guān)屬性,如名稱,類加載器,所屬容器等信息
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        //對(duì)BeanPostProcessor后置處理器的postProcessBeforeInitialization
        //回調(diào)方法的調(diào)用,為Bean實(shí)例初始化前做一些處理
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        //調(diào)用Bean實(shí)例對(duì)象初始化的方法,這個(gè)初始化方法是在Spring Bean定義配置
        //文件中通過init-method屬性指定的
        try {
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        //對(duì)BeanPostProcessor后置處理器的postProcessAfterInitialization
        //回調(diào)方法的調(diào)用,為Bean實(shí)例初始化之后做一些處理
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

至此,bean初始化操作的總體過程分析結(jié)束,當(dāng)然中間存在一些細(xì)節(jié)方面的點(diǎn)沒有分析清楚,還需要各位小伙伴自行研究,然后有什么問題可以留言,大家一起討論一起進(jìn)步。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77024.html

相關(guān)文章

  • Spring專題Bean始化源碼分析(1)

    摘要:初始化我們知道容器初始化后會(huì)對(duì)容器中非懶加載的,單例的以及非抽象的定義進(jìn)行的初始化操作,所以我們分析源碼的入口也就是在容器初始化的入口,分析容器初始化后在什么地方開始第一次的初始化。 前言 Spring IOC容器在初始化之后會(huì)對(duì)容器中非懶加載的,單例的以及非抽象的bean定義進(jìn)行bean的初始化操作,同時(shí)會(huì)也涉及到Bean的后置處理器以及DI(依賴注入)等行為。對(duì)于Bean的初始化,...

    harryhappy 評(píng)論0 收藏0
  • Spring專題IOC源碼分析

    摘要:前言以下源碼基于版本解析。實(shí)現(xiàn)源碼分析對(duì)于的實(shí)現(xiàn),總結(jié)來說就是定位加載和注冊。定位就是需要定位配置文件的位置,加載就是將配置文件加載進(jìn)內(nèi)存注冊就是通過解析配置文件注冊。下面我們從其中的一種使用的方式一步一步的分析的實(shí)現(xiàn)源碼。 前言 以下源碼基于Spring 5.0.2版本解析。 什么是IOC容器? 容器,顧名思義可以用來容納一切事物。我們平常所說的Spring IOC容器就是一個(gè)可以容...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • Spring注解專題系類(二)

    摘要:的在單例被破壞時(shí)由進(jìn)行方法調(diào)用。定義并實(shí)現(xiàn)這兩個(gè)接口容器創(chuàng)建完成注解是的縮寫,意思是規(guī)范提案。在創(chuàng)建完成并且屬性賦值完成來執(zhí)行初始化方法在容器銷毀之前回調(diào)通知支持自動(dòng)裝配,類似。 Spring注解應(yīng)用篇--IOC容器Bean生命周期 這是Spring注解專題系類文章,本系類文章適合Spring入門者或者原理入門者,小編會(huì)在本系類文章下進(jìn)行企業(yè)級(jí)應(yīng)用實(shí)戰(zhàn)講解以及spring源碼跟進(jìn)。本文...

    Alex 評(píng)論0 收藏0
  • 慕課網(wǎng)_《Spring入門篇》學(xué)習(xí)總結(jié)

    摘要:入門篇學(xué)習(xí)總結(jié)時(shí)間年月日星期三說明本文部分內(nèi)容均來自慕課網(wǎng)。主要的功能是日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等等。 《Spring入門篇》學(xué)習(xí)總結(jié) 時(shí)間:2017年1月18日星期三說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:https://github.com/zccodere/s...個(gè)人學(xué)習(xí)源碼:https://git...

    Ververica 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<