Rising Sun

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            148 隨筆 :: 0 文章 :: 22 評論 :: 0 Trackbacks
          http://singleant.iteye.com/blog/1177358

           

          接上文 啃啃老菜: Spring IOC核心源碼學(xué)習(xí)(一) ,本文將以 ClassPathXmlApplicationContext 這個容器的實現(xiàn)作為基礎(chǔ),學(xué)習(xí)容器的初始化過程。

          ClassPathXmlApplicationContext 類體系結(jié)構(gòu)

          以下是 ClassPathXmlApplicationContext 的類繼承體系結(jié)構(gòu),理解這個結(jié)構(gòu)有助于后面的代碼理解。

           


           

          左邊黃色部分是 ApplicationContext 體系繼承結(jié)構(gòu),右邊是 BeanFactory 的結(jié)構(gòu)體系,兩個結(jié)構(gòu)是典型模板方法設(shè)計模式的使用。

          從該繼承體系可以看出:

          1.       BeanFactory 是一個 bean 工廠的最基本定義,里面包含了一個 bean 工廠的幾個最基本的方法,getBean(…) 、 containsBean(…) 等 ,是一個很純粹的bean工廠,不關(guān)注資源、資源位置、事件等。ApplicationContext 是一個容器的最基本接口定義,它繼承了 BeanFactory, 擁有工廠的基本方法。同時繼承了ApplicationEventPublisher 、 MessageSource 、 ResourcePatternResolver 等接口,使其 定義了一些額外的功能,如資源、事件等這些額外的功能。

          2.      AbstractBeanFactory 和 AbstractAutowireCapableBeanFactory 是兩個模板抽象工廠類。AbstractBeanFactory 提供了 bean 工廠的抽象基類,同時提供了 ConfigurableBeanFactory 的完整實現(xiàn)。AbstractAutowireCapableBeanFactory 是繼承了 AbstractBeanFactory 的抽象工廠,里面提供了 bean 創(chuàng)建的支持,包括 bean 的創(chuàng)建、依賴注入、檢查等等功能,是一個核心的 bean 工廠基類。

          3.       ClassPathXmlApplicationContext之 所以擁有 bean 工廠的功能是通過持有一個真正的 bean 工廠DefaultListableBeanFactory 的實例,并通過 代理 該工廠完成。

          4.       ClassPathXmlApplicationContext 的初始化過程是對本身容器的初始化同時也是對其持有的DefaultListableBeanFactory 的初始化。

           

          下面通過源碼著重介紹一個容器的初始化過程,并重點理解 bean 的創(chuàng)建過程。

           

           

          容器初始化過程

          通過上文 啃啃老菜: Spring IOC核心源碼學(xué)習(xí)(一) 已經(jīng)可以了解一個容器的大概過程是:

           


           

           

          整個過程可以理解為是容器的初始化過程。第一個過程是 ApplicationContext 的職責(zé)范圍,第二步是 BeanFactory的職責(zé)范圍。可以看出 ApplicationContext 是一個運行時的容器需要提供不容資源環(huán)境的支持,屏蔽不同環(huán)境的差異化。而 BeanDifinition 是內(nèi)部關(guān)于 bean 定義的基本結(jié)構(gòu)。 Bean 的創(chuàng)建就是基于它,回頭會介紹一下改結(jié)構(gòu)的定義。下面看一下整個容器的初始化過程。

           

          容器的初始化是通過調(diào)用 refresh() 來實現(xiàn)。該方法是非常重要的一個方法,定義在 AbstractApplicationContext接口里。 AbstractApplicationContext 是容器的最基礎(chǔ)的一個抽象父類。也就是說在該里面定義了一個容器初始化的基本流程,流程里的各個方法有些有提供了具體實現(xiàn),有些是抽象的 ( 因為不同的容器實例不一樣 ) ,由繼承它的每一個具體容器完成定制。看看 refresh 的基本流程:

          Java代碼  收藏代碼
          1. public void refresh() throws BeansException, IllegalStateException {  
          2.         synchronized (this.startupShutdownMonitor) {  
          3.             // Prepare this context for refreshing.  
          4.             prepareRefresh();  
          5.             // Tell the subclass to refresh the internal bean factory.  
          6.             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  
          7.             // Prepare the bean factory for use in this context.  
          8.             prepareBeanFactory(beanFactory);  
          9.             try {  
          10.                 // Allows post-processing of the bean factory in context subclasses.  
          11.                 postProcessBeanFactory(beanFactory);  
          12.                 // Invoke factory processors registered as beans in the context.  
          13.                 invokeBeanFactoryPostProcessors(beanFactory);  
          14.                 // Register bean processors that intercept bean creation.  
          15.                 registerBeanPostProcessors(beanFactory);  
          16.                 // Initialize message source for this context.  
          17.                 initMessageSource();  
          18.                 // Initialize event multicaster for this context.  
          19.                 initApplicationEventMulticaster();  
          20.                 // Initialize other special beans in specific context subclasses.  
          21.                 onRefresh();  
          22.                 // Check for listener beans and register them.  
          23.                 registerListeners();  
          24.                 // Instantiate all remaining (non-lazy-init) singletons.  
          25.                 finishBeanFactoryInitialization(beanFactory);  
          26.                 // Last step: publish corresponding event.  
          27.                 finishRefresh();  
          28.             }  
          29.             catch (BeansException ex) {  
          30.                 // Destroy already created singletons to avoid dangling resources.  
          31.                 beanFactory.destroySingletons();  
          32.                 // Reset 'active' flag.  
          33.                 cancelRefresh(ex);  
          34.                 // Propagate exception to caller.  
          35.                 throw ex;  
          36.             }  
          37.         }  
          38.     }  
           

          解釋如下:

           


           

           

          Bean 的創(chuàng)建過程

          Bean的創(chuàng)建過程基本是BeanFactory所要完成的事情.

          根據(jù)以上過程,將會重點帶著以下兩個個問題來理解核心代碼:

          1.Bean 的創(chuàng)建時機(jī)

          bean 是在什么時候被創(chuàng)建的,有哪些規(guī)則。

          2.Bean 的創(chuàng)建過程

          bean 是怎么創(chuàng)建的,會選擇哪個構(gòu)造函數(shù)?依賴如何注入? InitializingBean 的 set 方法什么時候被調(diào)用?實現(xiàn)ApplicationContextAware, BeanFactoryAware,BeanNameAware, ResourceLoaderAware 這些接口的 bean 的set 方法何時被調(diào)用?

           

          在解釋這兩個問題前,先看一下 BeanDefinition 接口的定義。

            

           

          從該接口定義可以看出,通過 bean 定義能夠得到 bean 的詳細(xì)信息,如類名子、工廠類名稱、 scope 、是否單例、是否抽象、是否延遲加載等等。基于此,來看一下以下兩個問題:

           

           

           

           

          問題 1 : Bean 的創(chuàng)建時機(jī)

          bean 是在什么時候被創(chuàng)建的,有哪些規(guī)則?

          容器初始化的時候會預(yù)先對單例和非延遲加載的對象進(jìn)行預(yù)先初始化。其他的都是延遲加載是在第一次調(diào)用getBean 的時候被創(chuàng)建。從 DefaultListableBeanFactory 的 preInstantiateSingletons 里可以看到這個規(guī)則的實現(xiàn)。

          Java代碼  收藏代碼
          1. public void preInstantiateSingletons() throws BeansException {  
          2.         if (this.logger.isInfoEnabled()) {  
          3.             this.logger.info("Pre-instantiating singletons in " + this);  
          4.         }  
          5.   
          6.         synchronized (this.beanDefinitionMap) {  
          7.             for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) {  
          8.                 String beanName = (String) it.next();  
          9.                 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);  
          10.                 <span style="color: #ff0000;">if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {</span>  
          11.   
          12.   
          13.   
          14. //對非抽象、單例的和非延遲加載的對象進(jìn)行實例化。  
          15.                     if (isFactoryBean(beanName)) {  
          16.                         FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);  
          17.                         if (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()) {  
          18.                             getBean(beanName);  
          19.                         }  
          20.                     }  
          21.                     else {  
          22.                         getBean(beanName);  
          23.                     }  
          24.                 }  
          25.             }  
          26.         }  
          27.     }  
           


           從上面來看對于以下配置,只有 singletonBean 會被預(yù)先創(chuàng)建。

          Xml代碼  收藏代碼
          1. <?xml version="1.0" encoding="GB2312"?>  
          2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">  
          3. <beans default-autowire="byName">  
          4.     <bean id="otherBean"          class="com.test.OtherBean" scope="prototype"/>  
          5.     <bean id="myBean"          class="com.test.MyBean" lazy-init="true"/>  
          6.     <bean id="singletonBean"          class="com.test.SingletonBean"/>  
          7. </beans>  
           

           

           

           

          問題二:Bean 的創(chuàng)建過程

          對于 bean 的創(chuàng)建過程其實都是通過調(diào)用工廠的 getBean 方法來完成的。這里面將會完成對構(gòu)造函數(shù)的選擇、依賴注入等。

           

          無論預(yù)先創(chuàng)建還是延遲加載都是調(diào)用getBean實現(xiàn),AbstractBeanFactory 定義了 getBean 的過程:

          Java代碼  收藏代碼
          1. protected Object doGetBean(  
          2.             final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {  
          3.         final String beanName = transformedBeanName(name);  
          4.         Object bean = null;  
          5.         // Eagerly check singleton cache for manually registered singletons.  
          6.         Object sharedInstance = getSingleton(beanName);  
          7.         if (sharedInstance != null && args == null) {  
          8.             if (logger.isDebugEnabled()) {  
          9.                 if (isSingletonCurrentlyInCreation(beanName)) {  
          10.                     logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +  
          11.                             "' that is not fully initialized yet - a consequence of a circular reference");  
          12.                 }  
          13.                 else {  
          14.                     logger.debug("Returning cached instance of singleton bean '" + beanName + "'");  
          15.                 }  
          16.             }  
          17.             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
          18.         }  
          19.         else {  
          20.             // Fail if we're already creating this bean instance:  
          21.             // We're assumably within a circular reference.  
          22.             if (isPrototypeCurrentlyInCreation(beanName)) {  
          23.                 throw new BeanCurrentlyInCreationException(beanName);  
          24.             }  
          25.   
          26.             // Check if bean definition exists in this factory.  
          27.             BeanFactory parentBeanFactory = getParentBeanFactory();  
          28.             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {  
          29.                 // Not found -> check parent.  
          30.                 String nameToLookup = originalBeanName(name);  
          31.                 if (args != null) {  
          32.                     // Delegation to parent with explicit args.  
          33.                     return parentBeanFactory.getBean(nameToLookup, args);  
          34.                 }  
          35.                 else {  
          36.                     // No args -> delegate to standard getBean method.  
          37.                     return parentBeanFactory.getBean(nameToLookup, requiredType);  
          38.                 }  
          39.             }  
          40.   
          41.             if (!typeCheckOnly) {  
          42.                 markBeanAsCreated(beanName);  
          43.             }  
          44.   
          45.             final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);  
          46.             checkMergedBeanDefinition(mbd, beanName, args);  
          47.   
          48.             // Guarantee initialization of beans that the current bean depends on.  
          49.             String[] dependsOn = mbd.getDependsOn();  
          50.             if (dependsOn != null) {  
          51.                 for (int i = 0; i < dependsOn.length; i++) {  
          52.                     String dependsOnBean = dependsOn[i];  
          53.                     getBean(dependsOnBean);  
          54.                     registerDependentBean(dependsOnBean, beanName);  
          55.                 }  
          56.             }  
          57.             // Create bean instance.  
          58.             <span style="color: #ff0000;">if (mbd.isSingleton()) {//單例對象創(chuàng)建過程,間接通過getSingleton方法來創(chuàng)建,里面會實現(xiàn)將單例對象緩存</span>  
          59.   
          60.   
          61.   
          62.   
          63.                 sharedInstance = getSingleton(beanName, new ObjectFactory() {  
          64.                     public Object getObject() throws BeansException {  
          65.                         try {  
          66.                             return createBean(beanName, mbd, args);  
          67.                         }  
          68.                         catch (BeansException ex) {  
          69.                             // Explicitly remove instance from singleton cache: It might have been put there  
          70.                             // eagerly by the creation process, to allow for circular reference resolution.  
          71.                             // Also remove any beans that received a temporary reference to the bean.  
          72.                             destroySingleton(beanName);  
          73.                             throw ex;  
          74.                         }  
          75.                     }  
          76.                 });  
          77.                 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  
          78.             }  
          79.   
          80.             <span style="color: #ff0000;">else if (mbd.isPrototype()) {//非單例對象創(chuàng)建</span>  
          81.   
          82.   
          83.   
          84.   
          85.                 // It's a prototype -> create a new instance.  
          86.                 Object prototypeInstance = null;  
          87.                 try {  
          88.                     beforePrototypeCreation(beanName);  
          89.                     prototypeInstance = createBean(beanName, mbd, args);<span style="color: #ff0000;">//直接調(diào)用createBean</span>  
          90.   
          91.   
          92.   
          93.   
          94.                 }  
          95.                 finally {  
          96.                     afterPrototypeCreation(beanName);  
          97.                 }  
          98.                 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);  
          99.             }  
          100.   
          101.             else {  
          102.                 String scopeName = mbd.getScope();  
          103.                 final Scope scope = (Scope) this.scopes.get(scopeName);  
          104.                 if (scope == null) {  
          105.                     throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");  
          106.                 }  
          107.                 try {  
          108.                     Object scopedInstance = scope.get(beanName, new ObjectFactory() {  
          109.                         public Object getObject() throws BeansException {  
          110.                             beforePrototypeCreation(beanName);  
          111.                             try {  
          112.                                 return createBean(beanName, mbd, args);  
          113.                             }  
          114.                             finally {  
          115.                                 afterPrototypeCreation(beanName);  
          116.                             }  
          117.                         }  
          118.                     });  
          119.                     bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);  
          120.                 }  
          121.                 catch (IllegalStateException ex) {  
          122.                     throw new BeanCreationException(beanName,  
          123.                             "Scope '" + scopeName + "' is not active for the current thread; " +  
          124.                             "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",  
          125.                             ex);  
          126.                 }  
          127.             }  
          128.         }  
          129.         // Check if required type matches the type of the actual bean instance.  
          130.         if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {  
          131.             throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());  
          132.         }  
          133.         return bean;  
          134.     }  

           

           

           

           

          GetBean 的大概過程:

          1.       先試著從單例緩存對象里獲取。

          2.       從父容器里取定義,有則由父容器創(chuàng)建。

          3.       如果是單例,則走單例對象的創(chuàng)建過程:在 spring 容器里單例對象和非單例對象的創(chuàng)建過程是一樣的。都會調(diào)用父類 AbstractAutowireCapableBeanFactory 的 createBean 方法。 不同的是單例對象只創(chuàng)建一次并且需要緩存起來。 DefaultListableBeanFactory 的父類 DefaultSingletonBeanRegistry 提供了對單例對象緩存等支持工作。所以是單例對象的話會調(diào)用 DefaultSingletonBeanRegistry 的 getSingleton 方法,它會間接調(diào)用AbstractAutowireCapableBeanFactory 的 createBean 方法。

          如果是 Prototype 多例則直接調(diào)用父類 AbstractAutowireCapableBeanFactory 的 createBean 方法。

           

          bean的創(chuàng)建是由AbstractAutowireCapableBeanFactory來定義:

           

          Java代碼  收藏代碼
          1. protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)  
          2.             throws BeanCreationException {  
          3.         AccessControlContext acc = AccessController.getContext();  
          4.         return AccessController.doPrivileged(new PrivilegedAction() {  
          5.             public Object run() {  
          6.                 if (logger.isDebugEnabled()) {  
          7.                     logger.debug("Creating instance of bean '" + beanName + "'");  
          8.                 }  
          9.                 // Make sure bean class is actually resolved at this point.  
          10.                 resolveBeanClass(mbd, beanName);  
          11.                 // Prepare method overrides.  
          12.                 try {  
          13.                     mbd.prepareMethodOverrides();  
          14.                 }  
          15.                 catch (BeanDefinitionValidationException ex) {  
          16.                     throw new BeanDefinitionStoreException(mbd.getResourceDescription(),  
          17.                             beanName, "Validation of method overrides failed", ex);  
          18.                 }  
          19.                 try {  
          20.                     // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.  
          21.                     Object bean = resolveBeforeInstantiation(beanName, mbd);  
          22.                     if (bean != null) {  
          23.                         return bean;  
          24.                     }  
          25.                 }  
          26.                 catch (Throwable ex) {  
          27.                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,  
          28.                             "BeanPostProcessor before instantiation of bean failed", ex);  
          29.                 }  
          30.                 Object beanInstance = doCreateBean(beanName, mbd, args);  
          31.                 if (logger.isDebugEnabled()) {  
          32.                     logger.debug("Finished creating instance of bean '" + beanName + "'");  
          33.                 }  
          34.                 return beanInstance;  
          35.             }  
          36.         }, acc);  
          37.     }  
           

          createBean 會調(diào)用 doCreateBean 方法:

           

          Java代碼  收藏代碼
          1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {  
          2.         // Instantiate the bean.  
          3.         BeanWrapper instanceWrapper = null;  
          4.         if (mbd.isSingleton()) {  
          5.             instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);  
          6.         }  
          7.         if (instanceWrapper == null) {  
          8.             instanceWrapper = createBeanInstance(beanName, mbd, args);  
          9.         }  
          10.         final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);  
          11.         Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);  
          12.   
          13.         // Allow post-processors to modify the merged bean definition.  
          14.         synchronized (mbd.postProcessingLock) {  
          15.             if (!mbd.postProcessed) {  
          16.                 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);  
          17.                 mbd.postProcessed = true;  
          18.             }  
          19.         }  
          20.   
          21.         // Eagerly cache singletons to be able to resolve circular references  
          22.         // even when triggered by lifecycle interfaces like BeanFactoryAware.  
          23.         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&  
          24.                 isSingletonCurrentlyInCreation(beanName));  
          25.         if (earlySingletonExposure) {  
          26.             if (logger.isDebugEnabled()) {  
          27.                 logger.debug("Eagerly caching bean '" + beanName +  
          28.                         "' to allow for resolving potential circular references");  
          29.             }  
          30.             addSingletonFactory(beanName, new ObjectFactory() {  
          31.                 public Object getObject() throws BeansException {  
          32.                     return getEarlyBeanReference(beanName, mbd, bean);  
          33.                 }  
          34.             });  
          35.         }  
          36.         // Initialize the bean instance.  
          37.         Object exposedObject = bean;  
          38.         try {  
          39.             populateBean(beanName, mbd, instanceWrapper);  
          40.             exposedObject = initializeBean(beanName, exposedObject, mbd);  
          41.         }  
          42.         catch (Throwable ex) {  
          43.             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {  
          44.                 throw (BeanCreationException) ex;  
          45.             }  
          46.             else {  
          47.                 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);  
          48.             }  
          49.         }  
          50.         if (earlySingletonExposure) {  
          51.             Object earlySingletonReference = getSingleton(beanName, false);  
          52.             if (earlySingletonReference != null) {  
          53.                 if (exposedObject == bean) {  
          54.                     exposedObject = earlySingletonReference;  
          55.                 }  
          56.                 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {  
          57.                     String[] dependentBeans = getDependentBeans(beanName);  
          58.                     Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);  
          59.                     for (int i = 0; i < dependentBeans.length; i++) {  
          60.                         String dependentBean = dependentBeans[i];  
          61.                         if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {                         actualDependentBeans.add(dependentBean);  
          62.                         }  
          63.                     }  
          64.                     if (!actualDependentBeans.isEmpty()) {  
          65.                         throw new BeanCurrentlyInCreationException(beanName,  
          66.                                 "Bean with name '" + beanName + "' has been injected into other beans [" +  
          67.                                 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +  
          68.                                 "] in its raw version as part of a circular reference, but has eventually been " +  
          69.                                 "wrapped. This means that said other beans do not use the final version of the " +  
          70.                                 "bean. This is often the result of over-eager type matching - consider using " +  
          71.                                 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");  
          72.                     }  
          73.                 }  
          74.             }  
          75.         }  
          76.         // Register bean as disposable.  
          77.         registerDisposableBeanIfNecessary(beanName, bean, mbd);  
          78.         return exposedObject;  
          79.     }  
           

           

          doCreateBean 的流程:

          1.     會創(chuàng)建一個 BeanWrapper 對象 用于存放實例化對象。

          2.     如果沒有指定構(gòu)造函數(shù),會通過反射拿到一個默認(rèn)的構(gòu)造函數(shù)對象,并賦予beanDefinition.resolvedConstructorOrFactoryMethod 。

          3.     調(diào)用 spring 的 BeanUtils 的 instantiateClass 方法,通過反射創(chuàng)建對象。

          4.     applyMergedBeanDefinitionPostProcessors

          5.     populateBean(beanName, mbd, instanceWrapper); 根據(jù)注入方式進(jìn)行注入。根據(jù)是否有依賴檢查進(jìn)行依賴檢查。

          執(zhí)行 bean 的注入里面會選擇注入類型:

          Java代碼  收藏代碼
          1. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||  
          2.                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
          3.             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  
          4.   
          5.             // Add property values based on autowire by name if applicable.  
          6.             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {  
          7.                 autowireByName(beanName, mbd, bw, newPvs);  
          8.             }<span style="color: #ff0000;">//根據(jù)名字注入</span>  
          9.   
          10.   
          11.   
          12.   
          13.   
          14.             // Add property values based on autowire by type if applicable.  
          15.             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
          16.                 autowireByType(beanName, mbd, bw, newPvs);  
          17.             }<span style="color: #ff0000;">//根據(jù)類型注入</span>  
          18.   
          19.   
          20.   
          21.   
          22.   
          23.             pvs = newPvs;  
          24.         }  
           

          6.      initializeBean(beanName, exposedObject, mbd);

          判斷是否實現(xiàn)了 BeanNameAware 、 BeanClassLoaderAware 等 spring 提供的接口,如果實現(xiàn)了,進(jìn)行默認(rèn)的注入。同時判斷是否實現(xiàn)了 InitializingBean 接口,如果是的話,調(diào)用 afterPropertySet 方法。

           

          Java代碼  收藏代碼
          1. protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {  
          2.         if (bean instanceof BeanNameAware) {  
          3.             ((BeanNameAware) bean).setBeanName(beanName);  
          4.         }  
          5.         if (bean instanceof BeanClassLoaderAware) {  
          6.             ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());  
          7.         }  
          8.         if (bean instanceof BeanFactoryAware) {  
          9.             ((BeanFactoryAware) bean).setBeanFactory(this);  
          10.         }  
          11.         Object wrappedBean = bean;  
          12.         if (mbd == null || !mbd.isSynthetic()) {  
          13.             wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);  
          14.         }  
          15. <span style="color: #ff0000;">      try {  
          16.             invokeInitMethods(beanName, wrappedBean, mbd);  
          17.         }</span>  
          18.   
          19.   
          20.   
          21.   
          22.         catch (Throwable ex) {  
          23.             throw new BeanCreationException(  
          24.                     (mbd != null ? mbd.getResourceDescription() : null),  
          25.                     beanName, "Invocation of init method failed", ex);  
          26.         }  
          27.   
          28.         if (mbd == null || !mbd.isSynthetic()) {  
          29.             wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);  
          30.         }  
          31.         return wrappedBean;  
          32.     }  

           其中invokeInitMethods實現(xiàn)如下:

          Java代碼  收藏代碼
          1. protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)  
          2.         throws Throwable {  
          3.   
          4.     boolean isInitializingBean = (bean instanceof InitializingBean);  
          5.     if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {  
          6.         if (logger.isDebugEnabled()) {  
          7.             logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");  
          8.         }  
          9.         ((InitializingBean) bean).afterPropertiesSet();<span style="color: #ff0000;">//調(diào)用afterPropertiesSet方法</span>  
          10.   
          11.   
          12.   
          13.   
          14.     }  
          15.   
          16.     String initMethodName = (mbd != null ? mbd.getInitMethodName() : null);  
          17.     if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&  
          18.             !mbd.isExternallyManagedInitMethod(initMethodName)) {  
          19.         invokeCustomInitMethod(beanName, bean, initMethodName, mbd.isEnforceInitMethod());  
          20.     }  
          21. }  
           

           

           

          總結(jié)

          以上基本描述了 spring 容器的初始化過程和 bean 的創(chuàng)建過程。主要還是從大處著眼,很多細(xì)節(jié)沒有涉及到。代碼閱讀總體感覺就是 spring 的代碼抽象很好,結(jié)合結(jié)構(gòu)讀起來還是蠻順利的。后面的學(xué)習(xí)將從細(xì)節(jié)著手。

          下面源碼學(xué)習(xí)預(yù)告:

          1.       Spring 的聲明式標(biāo)簽如實現(xiàn)

          2.       Spring aop 代理如何實現(xiàn)

          posted on 2013-02-28 11:04 brock 閱讀(826) 評論(0)  編輯  收藏 所屬分類: 學(xué)習(xí)總結(jié)
          主站蜘蛛池模板: 商洛市| 龙门县| 浮梁县| 曲阜市| 延津县| 湖南省| 柏乡县| 海南省| 大宁县| 龙州县| 芷江| 奈曼旗| 河源市| 阿坝县| 盈江县| 正宁县| 南木林县| 皮山县| 洱源县| 大关县| 锦屏县| 秭归县| 内黄县| 佳木斯市| 扎兰屯市| 青海省| 高州市| 峡江县| 元江| 潢川县| 尚志市| 鄂温| 余姚市| 姚安县| 吉木乃县| 扬州市| 南召县| 黄梅县| 营山县| 梁河县| 山阳县|