Spring IoC容器初始化

Spring IoC容器的初始化,主要分為三段

  1. 啟動(dòng)容器友扰,掃描指定包路徑下的Bean,封裝BeanDefinition

    啟動(dòng)容器的三種方式:ClassPathXmlApplicationContext士败、AnnotationConfigApplicationContext控汉、FileSystemXmlApplicationContext在抛; 分別會(huì)走不同的掃描方式钟病,最終完成BeanDefinition的封裝。

  2. 裝配BeanFactory

  3. 根據(jù)SpringBean的生命周期中定義的創(chuàng)建流程刚梭,創(chuàng)建Bean對(duì)象肠阱。無(wú)論以哪一種方式啟動(dòng)容器,最終都會(huì)交由AbstractApplicationContext類執(zhí)行refresh方法進(jìn)行Bean對(duì)象的創(chuàng)建

循環(huán)依賴

在Spring容器的初始化過(guò)程中朴读,繞不開(kāi)2個(gè)及以上Bean對(duì)象的相互依賴問(wèn)題屹徘,Spring稱之為循環(huán)依賴(circular references)

三級(jí)緩存

Spring對(duì)于循環(huán)依賴問(wèn)題,提供了使用三級(jí)緩存的解決策略衅金。分別為

  • singletonFactories:三級(jí)緩存噪伊,存放的是ObjectFactory,注意此處存放的不是bean對(duì)象氮唯,而是生成bean對(duì)象的factory對(duì)象酥宴。
  • earlySingletonObjects:二級(jí)緩存,存放的是由三級(jí)緩存中ObjectFactory對(duì)象執(zhí)行g(shù)etObject方法生成的代理對(duì)象您觉,完成Spring通過(guò)動(dòng)態(tài)代理的方式,對(duì)bean中的方法實(shí)現(xiàn)增強(qiáng)授滓。此時(shí)該代理對(duì)象尚未開(kāi)始屬性注入琳水。
  • singletonObjects:一級(jí)緩存肆糕,即最終Spring容器中的單例池,存放最終完成所有屬性注入的完整bean對(duì)象在孝。

值得注意的是:Spring在初始化Bean的過(guò)程中诚啃,并不能預(yù)先確認(rèn)該Bean是否存在循環(huán)依賴的情況。因此所有Bean對(duì)象(無(wú)論有無(wú)循環(huán)依賴)私沮,在被實(shí)例化之后始赎,屬性注入之前,都會(huì)被放入三級(jí)緩存singletonFactories中仔燕,走相同的初始化流程造垛。

初始化Bean處理AutoWired.png

為什么要使用三級(jí)緩存

看了一些關(guān)于三級(jí)緩存的博客,大部分都有描述這個(gè)問(wèn)題晰搀。簡(jiǎn)單回答:需要遵守設(shè)計(jì)的“單一原則”五辽,各級(jí)緩存各司其職。

這又衍生出另一個(gè)問(wèn)題:第三級(jí)緩存的存在外恕,到底在設(shè)計(jì)上有何優(yōu)雅或者必要之處杆逗?

實(shí)際上這個(gè)三級(jí)緩存中的ObjectFactory會(huì)在Bean對(duì)象第一次屬性依賴(注意不一定是循環(huán)依賴的情況)注入時(shí),就執(zhí)行它的getObject方法鳞疲,獲取增強(qiáng)后的代理對(duì)象罪郊,放入二級(jí)緩存中;此后尚洽,在每一次循環(huán)依賴屬性注入時(shí)悔橄,都會(huì)從二級(jí)緩存中取得代理對(duì)象進(jìn)行注入。也就是說(shuō)翎朱,如果根本就沒(méi)有三級(jí)緩存橄维,直接執(zhí)行掉ObjectFactory.getObject方法里的操作,獲取代理對(duì)象后放入二級(jí)緩存中拴曲。理論上也是可以的争舞,這樣似乎三級(jí)緩存就沒(méi)必要了?不用懷疑ObjectFactory.getObject里的操作的執(zhí)行時(shí)機(jī)問(wèn)題澈灼,里面只是一些純粹的增強(qiáng)竞川。

下圖是源碼追蹤Spring解決循環(huán)依賴問(wèn)題的時(shí)序圖,也是Spring Bean初始化與屬性注入的大致流程:

Spring Bean循環(huán)依賴.png

以下源碼分析的過(guò)程叁熔,對(duì)不關(guān)注的代碼進(jìn)行了刪減

通過(guò)ClassPathXmlApplicationContext啟動(dòng)容器:

public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {

        super(parent);
        // sy 掃描配置文件委乌,封裝BeanDefinition對(duì)象 -- 所有的啟動(dòng)方式在構(gòu)造函數(shù)中,都會(huì)先走配置掃描荣回,做BeanDefinition封裝遭贸。
        //      之后統(tǒng)一走AbstractApplicationContext:refresh();進(jìn)行容器初始化
        // ClassPathXmlApplicationContext:setConfigLocations(configLocations);
        // FileSystemXmlApplicationContext:setConfigLocations(configLocations);
        // AnnotationConfigApplicationContext(Class<?>... componentClasses):register(componentClasses);
        // AnnotationConfigApplicationContext(String... basePackages):scan(basePackages);
        // -- AbstractApplicationContext:refresh();
        setConfigLocations(configLocations);
        if (refresh) {
            // sy 初始化IoC容器
            refresh();
        }
    }

ClassPathXmlApplicationContext的構(gòu)造函數(shù)最終走AbstractApplicationContext.refresh方法,完成BeanFactory與Bean的建立

AbstractApplicationContext#refresh

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            // sy 獲取BeanFactory
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            // sy 預(yù)裝配BeanFactory
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                // sy 模板方法
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                // sy 設(shè)置工程中實(shí)現(xiàn)的BeanFactoryPostProcessors并執(zhí)行postProcessBeanFactory方法
                // 最終通過(guò)DefaultListableBeanFactory.doGetBeanNamesForType遍歷beanDefinitionNames獲取BeanFactoryPostProcessors心软。
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // sy 注冊(cè)BeanPostProcessors
                // 調(diào)用時(shí)機(jī):Bean實(shí)例化 -> Bean對(duì)象屬性注入 -> BeanNameAware.setBeanName -> BeanFactoryAware.setBeanFactory -> ApplicationContextAware.setApplicationContext
                //          -> **** BeanPostProcessor.postProcessBeforeInitialization ****
                //              -> InitializingBean.afterPropertiesSet -> 調(diào)用xml定制的init-method方法或者Bean中用@PostConstruct注解的方法
                //          -> **** BeanPostProcessor.postProcessAfterInitialization  ****
                //              -> Singleton:放入單例池中壕吹,由Spring容器管理; Prototype:交給調(diào)用者著蛙,由JVM管理
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                // sy 國(guó)際化
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                // sy 最終完成IoC注入的調(diào)用
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

執(zhí)行AbstractApplicationContext#finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 初始化Bean
        beanFactory.preInstantiateSingletons();
    }

執(zhí)行DefaultListableBeanFactory#preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("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...
        // sy 通過(guò)遍歷封裝完畢的BeanDefinition,逐一創(chuàng)建Spring Bean
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    // sy 處理FactoryBean
                    //  從容器中獲取FactoryBean時(shí)耳贬,使用"&"+beanName的原因
                    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) {
                            // sy 初始化bean
                            getBean(beanName);
                        }
                    }
                }
                else {
                    // sy 初始化bean
                    getBean(beanName);
                }
            }
        }

        // Trigger post-initialization callback for all applicable beans...
        for (String beanName : beanNames) {
            // 逐一從一級(jí)緩存踏堡、二級(jí)緩存、三級(jí)緩存中獲取實(shí)例化對(duì)象
            Object singletonInstance = getSingleton(beanName);
            // 對(duì)單例bean對(duì)象的后置增強(qiáng)
            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();
                }
            }
        }
    }

執(zhí)行AbstractBeanFactory#getBean -> 調(diào)用內(nèi)部AbstractBeanFactory#doGetBean方法

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

        final String beanName = transformedBeanName(name);
        Object bean;

        // Eagerly check singleton cache for manually registered singletons.
        // sy 依次從一級(jí)緩存咒劲、二級(jí)緩存顷蟆、三級(jí)緩存中獲取bean對(duì)象
        Object sharedInstance = getSingleton(beanName);
        // sy 如果已獲得bean且其無(wú)參構(gòu)造
        if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            // sy 處理factoryBean的情況
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            // sy 如果當(dāng)前的bean的scope為prototype,則拋出異常腐魂,prototype類型的bean不應(yīng)該在初始化階段生成
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            // sy 根據(jù)得到的BeanFactory做getBean遞歸
            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);
                }
            }

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

                // Guarantee initialization of beans that the current bean depends on.
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        registerDependentBean(dep, beanName);
                        try {
                            // sy 遞歸創(chuàng)建依賴對(duì)象
                            getBean(dep);
                        }
                    }
                }

                // Create bean instance.
                if (mbd.isSingleton()) {
                    // sy 看命名應(yīng)該能明白帐偎,該方法最終返回了一個(gè)singleton的bean對(duì)象,即存放在singletonObjects(一級(jí)緩存單例池中的對(duì)象)
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            // sy 最終創(chuàng)建bean代理對(duì)象的地方
                            return createBean(beanName, mbd, args);
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
            }
        }
    
        return (T) bean;
    }

如果能使用DefaultListableBeanFactory#preInstantiateSingletons.getSingleton方法從緩存中得到bean挤渔,則之前已走過(guò)實(shí)例化流程肮街。該方法很關(guān)鍵:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        // sy 如果對(duì)象不在單例池singletonObjects(一級(jí)緩存)中
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                // sy 如果對(duì)象不在二級(jí)緩存earlySingletonObjects中
                if (singletonObject == null && allowEarlyReference) {
                    // sy 從三級(jí)緩存singletonFactories中獲取中獲取ObjectFactory
                    //      注意三級(jí)緩存singletonFactories中存放的是ObjectFactory,并不是bean對(duì)象判导,即此時(shí)沒(méi)有生成bean的代理對(duì)象
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        // sy 通過(guò)匿名內(nèi)部類實(shí)現(xiàn)ObjectFactory接口的getObject嫉父,創(chuàng)建Bean對(duì)象
                        //      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
                        singletonObject = singletonFactory.getObject();
                        // sy 將生成的Bean對(duì)象放入二級(jí)緩存中
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        // sy 從一級(jí)緩存中移除使用beanName標(biāo)記的ObjectFactory
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

如果從緩存中獲取不到bean,說(shuō)明該Bean對(duì)象尚未進(jìn)行實(shí)例化眼刃,走org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton方法:

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   synchronized (this.singletonObjects) {
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
         beforeSingletonCreation(beanName);
         boolean newSingleton = false;
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }
         try {
            // sy 執(zhí)行beanFactory的getObject方法即:
            //        () -> {
            //                try {
            //                   // sy 最終創(chuàng)建bean代理對(duì)象的地方(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean)
            //                   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;
            //                }
            //             }
            //    創(chuàng)建最終完成增強(qiáng)的完整的singleton代理對(duì)象
            //    并在下方執(zhí)行addSingleton(beanName, singletonObject)绕辖,將其放進(jìn)單例緩存池中,并將其從三級(jí)擂红、二級(jí)緩存中刪除
            singletonObject = singletonFactory.getObject();
            newSingleton = true;
         }
         finally {
            if (recordSuppressedExceptions) {
               this.suppressedExceptions = null;
            }
            afterSingletonCreation(beanName);
         }
         if (newSingleton) {
            // sy 將初始化完成的bean對(duì)象放入單例池中
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

由singletonObject = singletonFactory.getObject()執(zhí)行org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean方法:這里刪除了異常處理的代碼仪际,主要關(guān)注2個(gè)方法:resolveBeforeInstantiation、doCreateBean(最終創(chuàng)建Bean對(duì)象)

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

        RootBeanDefinition mbdToUse = mbd;

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            // sy 聽(tīng)名字有點(diǎn)疑惑昵骤,
            //  設(shè)置BeanPostProcessors的postProcessBeforeInitialization树碱,postProcessAfterInitialization。
            //  這樣似乎說(shuō)明會(huì)在Bean依賴注入完畢就立馬執(zhí)行BeanPostProcessor 变秦?
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }

        try {
            // sy 創(chuàng)建bean對(duì)象
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            return beanInstance;
        }
    }

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean這個(gè)方法做了3件事:

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

    將ObjectFactory加入三級(jí)緩存中

  • populateBean(beanName, mbd, instanceWrapper)
    

    進(jìn)行屬性注入

  • exposedObject = initializeBean(beanName, exposedObject, mbd)
    

    在bean裝配完成后成榜,執(zhí)行BeanPostProcessor與init-method

源碼詳解:

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

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      // sy factoryBeanInstanceCache.put前會(huì)將beanName做一步createBeanInstance
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   // sy 如果為空說(shuō)明當(dāng)前尚未創(chuàng)建過(guò)Bean對(duì)象
   if (instanceWrapper == null) {
      // sy 最終都會(huì)走createBeanInstance方法去實(shí)例化對(duì)象,僅僅只是實(shí)例化原生對(duì)象蹦玫,尚未對(duì)bean對(duì)象進(jìn)行屬性注入赎婚,也未生成代理對(duì)象且增強(qiáng)
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   final Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         mbd.postProcessed = true;
      }
   }
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   if (earlySingletonExposure) {
      // sy 在bean實(shí)例化之后,將其BeanFactory:() -> getEarlyBeanReference(beanName, mbd, bean)放入三級(jí)緩存中樱溉,
      //        可解決循環(huán)依賴問(wèn)題(默認(rèn)開(kāi)啟允許循環(huán)依賴:this.allowCircularReferences的默認(rèn)值為true)
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      // sy 為bean對(duì)象執(zhí)行屬性注入挣输。
      populateBean(beanName, mbd, instanceWrapper);
      // sy 在bean裝配完成后,執(zhí)行BeanPostProcessor與init-method
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }

   // sy 如果在二級(jí)緩存中
   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);
               }
            }
         }
      }
   }

   // Register bean as disposable.
   try {
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }

   return exposedObject;
}

重點(diǎn)關(guān)注屬性裝配:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  
   // 前面做了一系列處理去獲取pvs:propertyValues
   if (pvs != null) {
      // sy 解決@AutoWired注入
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

最終調(diào)用了org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues:

這里面主要做了2件事

  • Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
    

    通過(guò)調(diào)用BeanDefinitionValueResolver.resolveValueIfNecessary獲取該屬性的值

  • bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    

    通過(guò)BeanWrapper.setPropertyValues方法將獲取的屬性值福贞,注入到屬性對(duì)象中撩嚼。內(nèi)部使用了PropertyAccessor(屬性存取器)做了一些處理,最終在org.springframework.beans.BeanWrapperImpl.BeanPropertyHandler#setValue方法中使用反射進(jìn)行屬性值注入:

    public void setValue(final @Nullable Object value) throws Exception {
       final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
             ((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
             this.pd.getWriteMethod());
       if (System.getSecurityManager() != null) {
          AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
             ReflectionUtils.makeAccessible(writeMethod);
             return null;
          });
          try {
             AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
                   writeMethod.invoke(getWrappedInstance(), value), acc);
          }
          catch (PrivilegedActionException ex) {
             throw ex.getException();
          }
       }
       else {
          // sy 暴力調(diào)用
          ReflectionUtils.makeAccessible(writeMethod);
          writeMethod.invoke(getWrappedInstance(), value);
       }
    }
    

最終該方法的源碼詳情:

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if (pvs.isEmpty()) {
            return;
        }
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        // Create a deep copy, resolving any references for values.
        List<PropertyValue> deepCopy = new ArrayList<>(original.size());
        boolean resolveNecessary = false;
        for (PropertyValue pv : original) {
            if (pv.isConverted()) {
                deepCopy.add(pv);
            }
            else {
                String propertyName = pv.getName();
                Object originalValue = pv.getValue();
                // sy 處理property的注入值
                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                Object convertedValue = resolvedValue;
                boolean convertible = bw.isWritableProperty(propertyName) &&
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                if (convertible) {
                    convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
                }
                if (resolvedValue == originalValue) {
                    if (convertible) {
                        pv.setConvertedValue(convertedValue);
                    }
                    deepCopy.add(pv);
                }
            }
        }

        // Set our (possibly massaged) deep copy.
        try {
            // sy 將獲取的屬性值,通過(guò)反射注入到屬性對(duì)象中
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
    }

進(jìn)入org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveValueIfNecessary方法:

public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
   // 這方法其實(shí)東西挺多的绢馍,處理的情況也比較多向瓷。大部分直接會(huì)走第一個(gè)if條件,就不看其他的了
   if (value instanceof RuntimeBeanReference) {
      RuntimeBeanReference ref = (RuntimeBeanReference) value;
      // sy 處理引用(即對(duì)象引用)
      return resolveReference(argName, ref);
   }
}

進(jìn)入org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference方法:

這個(gè)方法很關(guān)鍵舰涌,是下一輪遞歸的入口:

private Object resolveReference(Object argName, RuntimeBeanReference ref) {
   try {
      Object bean;
      String refName = ref.getBeanName();
      refName = String.valueOf(doEvaluate(refName));
      if (ref.isToParent()) {
         bean = this.beanFactory.getParentBeanFactory().getBean(refName);
      }
      else {
         // sy 很熟悉吧。又回到了最初的getBean你稚,算是一種遞歸吧瓷耙。
         //     遞歸結(jié)束的條件即在getBean方法中從三級(jí)到一級(jí)緩存內(nèi)獲取到了bean對(duì)象。此時(shí)該bean對(duì)象即增強(qiáng)后的代理對(duì)象了刁赖。
         //       如果在緩存內(nèi)未取得bean對(duì)象搁痛,則繼續(xù)向下遞歸,若取得宇弛,則向上回歸
         bean = this.beanFactory.getBean(refName);
         this.beanFactory.registerDependentBean(refName, this.beanName);
      }
      return bean;
   }
}

最終在最后一層遞歸完成鸡典,向上回歸到第一次getBean方法內(nèi)的getSingleton方法中,從一級(jí)緩存(單例池)中獲取完整對(duì)象后枪芒,實(shí)例化完成彻况。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市舅踪,隨后出現(xiàn)的幾起案子纽甘,更是在濱河造成了極大的恐慌,老刑警劉巖抽碌,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悍赢,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡货徙,警方通過(guò)查閱死者的電腦和手機(jī)左权,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)痴颊,“玉大人赏迟,你說(shuō)我怎么就攤上這事〉灰ǎ” “怎么了瀑梗?”我有些...
    開(kāi)封第一講書人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)裳扯。 經(jīng)常有香客問(wèn)我抛丽,道長(zhǎng),這世上最難降的妖魔是什么饰豺? 我笑而不...
    開(kāi)封第一講書人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任亿鲜,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蒿柳。我一直安慰自己饶套,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布垒探。 她就那樣靜靜地躺著妓蛮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪圾叼。 梳的紋絲不亂的頭發(fā)上蛤克,一...
    開(kāi)封第一講書人閱讀 52,184評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音夷蚊,去河邊找鬼构挤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惕鼓,可吹牛的內(nèi)容都是我干的筋现。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼箱歧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼矾飞!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起叫胁,我...
    開(kāi)封第一講書人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤凰慈,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后驼鹅,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體微谓,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年输钩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了豺型。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡买乃,死狀恐怖姻氨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情剪验,我是刑警寧澤肴焊,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站功戚,受9級(jí)特大地震影響娶眷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜啸臀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一届宠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦豌注、人聲如沸伤塌。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)每聪。三九已至,卻和暖如春齿风,著一層夾襖步出監(jiān)牢的瞬間熊痴,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工聂宾, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诊笤。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓系谐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親讨跟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子纪他,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容