Spring IOC容器的高級(jí)特性

通過(guò)之前對(duì)spring ioc的剖析值漫,我們了解到:Spring IOC容器對(duì)Bean定義資源的定位澳腹、讀入和解析y以及初始化和依賴(lài)注入過(guò)程,這些均屬于容器的基本功能特性杨何,接下來(lái)就容器的一些高級(jí)特性我們進(jìn)行相應(yīng)的學(xué)習(xí)酱塔。

1. 配置lazy-init屬性實(shí)現(xiàn)預(yù)實(shí)例化

我們已經(jīng)知道IOC容器的初始化過(guò)程就是對(duì)bean定義資源的定位、載入和注冊(cè)危虱,此時(shí)容器對(duì)bean的依賴(lài)注入并沒(méi)有發(fā)生羊娃,此時(shí):
bean的依賴(lài)注入:

  1. 發(fā)生時(shí)間:在應(yīng)用程序第一次向容器索取bean時(shí)。
  2. 方式:通過(guò)getBean方法的調(diào)用完成埃跷。

但是如果當(dāng)bean定義資源的<Bean>元素中配置了lazy-init屬性后蕊玷,容器將會(huì)在初始化時(shí)對(duì)所配置的bean進(jìn)行預(yù)實(shí)例化,此時(shí):
bean的依賴(lài)注入:

  1. 發(fā)生時(shí)間:容器初始化時(shí)已經(jīng)完成。
  2. 方式:容器初始化捌蚊。
  3. 當(dāng)應(yīng)用程序第一次向容器索取被管理的bean時(shí)集畅,直接從容器中獲取已經(jīng)完成依賴(lài)注入的bean,提高了應(yīng)用第一次向容器獲取bean的性能缅糟。

接下來(lái)挺智,通過(guò)剖析源碼分析其實(shí)現(xiàn)過(guò)程:
首先從AbstractApplicationContext類(lèi)的refresh方法開(kāi)始:

public void refresh() throws BeansException, IllegalStateException {  
       synchronized (this.startupShutdownMonitor) {  
           //調(diào)用容器準(zhǔn)備刷新的方法
           prepareRefresh();  

           /**調(diào)用子類(lèi)中refreshBeanFactory()方法 
          *啟動(dòng)Bean定義資源文件的過(guò)程
          */
           ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  

           //為BeanFactory配置容器特性
           prepareBeanFactory(beanFactory);  
           try {  
               //為容器的子類(lèi)指定事件處理器  
               postProcessBeanFactory(beanFactory);
  
               //調(diào)用所有注冊(cè)的BeanFactoryPostProcessor的Bean  
               invokeBeanFactoryPostProcessors(beanFactory);  

               /**為BeanFactory注冊(cè)BeanPost事件處理器.  
               *BeanPostProcessor是Bean后置處理器,用于監(jiān)聽(tīng)容器觸發(fā)的事件  
               */
               registerBeanPostProcessors(beanFactory);
  
               //初始化信息源
               initMessageSource();  

               //初始化容器事件傳播器.  
               initApplicationEventMulticaster();  

               //調(diào)用子類(lèi)Bean初始化方法  
               onRefresh();  

               //為事件傳播器注冊(cè)事件監(jiān)聽(tīng)器.  
               registerListeners();  
               //對(duì)容器lazy-init屬性處理的入口方法
               finishBeanFactoryInitialization(beanFactory);  

              /**初始化容器的生命周期事件處理器
              *并發(fā)布容器的生命周期事件  
              */
               finishRefresh();  
           }  
           catch (BeansException ex) {  
               destroyBeans();  
               cancelRefresh(ex);  
               throw ex;  
           }  
       }  
   }

其中:

//對(duì)容器lazy-init屬性處理的入口方法
finishBeanFactoryInitialization(beanFactory); 

此方法位于類(lèi)AbstractApplicationContext中窗宦,是對(duì)配置了預(yù)實(shí)例化屬性的bean進(jìn)行預(yù)初始化過(guò)程赦颇,源碼如下:

   //對(duì)配置了lazy-init屬性的bean進(jìn)行預(yù)實(shí)例化處理  
   protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {  
       if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&  
               beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {  
           beanFactory.setConversionService(  
                   beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));  
       }  
       beanFactory.setTempClassLoader(null);  
       //對(duì)容器中所有注冊(cè)的BeanDefinition緩存二鳄,防止在預(yù)實(shí)例化過(guò)程中被修改  
       beanFactory.freezeConfiguration();  
       //對(duì)配置了lazy-init屬性的單例模式下的bean進(jìn)行預(yù)實(shí)例化處理  
       beanFactory.preInstantiateSingletons();  
    }

方法preInstantiateSingletons對(duì)配置lazy-init屬性單例bean的預(yù)實(shí)例化:

//對(duì)配置lazy-init屬性單例bean的預(yù)實(shí)例化  
public void preInstantiateSingletons() throws BeansException {  
       if (this.logger.isInfoEnabled()) {  
           this.logger.info("Pre-instantiating singletons in " + this);  
       }  
       /**在對(duì)配置lazy-init屬性單例bean的預(yù)實(shí)例化過(guò)程中,
       *須保證多線(xiàn)程同步媒怯,以確保數(shù)據(jù)的一致性  
       */
       synchronized (this.beanDefinitionMap) {  
           for (String beanName : this.beanDefinitionNames) {  
               //獲取指定名稱(chēng)的bean定義  
               RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);  
               /*如果bean不是抽象的订讼,同時(shí)是單例模式的bean,
               *并且lazy-init屬性配置為false 
               */
               if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {  
                   //如果指定名稱(chēng)的bean是創(chuàng)建容器的bean  
                   if (isFactoryBean(beanName)) {  
                       final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);  
                       //標(biāo)識(shí)是否需要預(yù)實(shí)例化  
                       boolean isEagerInit;  
                       if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {  
                           isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {  
                               public Boolean run() {  
                                   return ((SmartFactoryBean) factory).isEagerInit();  
                               }  
                           }, getAccessControlContext());  
                       }  
                       else {  
                           isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit();   
                       }  
                       if (isEagerInit) {  
                           getBean(beanName);  
                       }  
                   }  
                   else {  
                       /*如果指定名稱(chēng)的bean不是創(chuàng)建容器的bean  
                       *調(diào)用getBean方法扇苞,觸發(fā)容器對(duì)bean實(shí)例化和依賴(lài)注入過(guò)程
                       */
                       getBean(beanName);  
                   }  
               }  
           }  
       }  
    }

經(jīng)過(guò)上述分析:
如果設(shè)置了lazy-init屬性欺殿,則容器在完成bean定義的注冊(cè)之后,會(huì)通過(guò)getBean方法鳖敷,觸發(fā)對(duì)指定Bean的初始化和依賴(lài)注入過(guò)程脖苏。
當(dāng)應(yīng)用第一次向容器索取所需的bean時(shí),容器不再需要對(duì)bean進(jìn)行初始化和依賴(lài)注入定踱,直接從已經(jīng)完成實(shí)例化和依賴(lài)注入的bean中取一個(gè)線(xiàn)程的bean棍潘,提高了第一次獲取bean的性能。

2. FactoryBean的實(shí)現(xiàn)

FactoryBean:

  1. 概念:工廠(chǎng)bean崖媚,本質(zhì)也是bean亦歉。
  2. 作用:產(chǎn)生其他bean實(shí)例提供一個(gè)工廠(chǎng)方法,該方法用來(lái)返回其他bean實(shí)例畅哑。

源碼如下:

//用于產(chǎn)生其他對(duì)象  
public interface FactoryBean<T> {  
   //獲取容器管理的對(duì)象實(shí)例  
    T getObject() throws Exception;  
    //獲取Bean工廠(chǎng)創(chuàng)建的對(duì)象的類(lèi)型  
    Class<?> getObjectType();  
    /*判斷bean工廠(chǎng)創(chuàng)建的對(duì)象是否是單態(tài)模式肴楷,
    *如果是單例模式,則整個(gè)容器中只有一個(gè)實(shí)例對(duì)象敢课,  
    *每次請(qǐng)求都返回同一個(gè)實(shí)例對(duì)象
    */
    boolean isSingleton();  
}

類(lèi)AbstractBeanFactory的doGetBean方法中使用FactoryBean:

  //真正實(shí)現(xiàn)向IOC容器獲取bean的方法阶祭,也是觸發(fā)依賴(lài)注入功能的地方  
   @SuppressWarnings("unchecked")  
   protected <T> T doGetBean(  
           final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)  
           throws BeansException {  
       /**根據(jù)指定名稱(chēng)獲取被管理bean名稱(chēng),首先剝離指定名稱(chēng)中對(duì)容器的相關(guān)依賴(lài)  
       *如果指定的是別名直秆,需要將別名轉(zhuǎn)換為規(guī)范的bean名稱(chēng)  
       */
       final String beanName = transformedBeanName(name);  
       Object bean;  
       /**先從緩存中取是否已經(jīng)有被創(chuàng)建過(guò)的單例類(lèi)型的bean濒募,
        *對(duì)于單例模式的bean整個(gè)IOC容器中只創(chuàng)建一次,不需要重復(fù)創(chuàng)建  
        */
       Object sharedInstance = getSingleton(beanName);  
       //IOC容器創(chuàng)建單態(tài)模式bean實(shí)例對(duì)象  
       if (sharedInstance != null && args == null) {  
           if (logger.isDebugEnabled()) {  
               /**如果指定名稱(chēng)的bean在容器中已存在單態(tài)模式的bean被創(chuàng)建圾结,
                *直接返回已經(jīng)創(chuàng)建的bean  
                */
               if (isSingletonCurrentlyInCreation(beanName)) {  
                   logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +  
                           "' that is not fully initialized yet - a consequence of a circular reference");  
               }  
               else {  
                   logger.debug("Returning cached instance of singleton bean '" + beanName + "'");  
               }  
           }  
           //獲取給定bean的實(shí)例對(duì)象
           bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
       }  
       .........................
   }

方法getObjectForBeanInstance完成FactoryBean的相關(guān)處理:

   //獲取給定bean的實(shí)例對(duì)象瑰剃,主要是完成FactoryBean的相關(guān)處理 
   protected Object getObjectForBeanInstance(  
           Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {  
       /**容器得到了bean實(shí)例對(duì)象,這個(gè)實(shí)例對(duì)象可能是一個(gè)普通的bean筝野,也可能是一個(gè)工廠(chǎng)bean晌姚,  
       *如果是一個(gè)工廠(chǎng)bean,則使用它創(chuàng)建一個(gè)bean實(shí)例對(duì)象歇竟,  
       *如果調(diào)用本身就想獲得一個(gè)容器的引用挥唠,則指定返回這個(gè)工廠(chǎng)bean實(shí)例對(duì)象 
       */  
       if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {  
           throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());  
       }  
       /**如果bean實(shí)例不是工廠(chǎng)bean,或者指定名稱(chēng)是容器的解引用焕议,  
       *調(diào)用者向獲取對(duì)容器的引用宝磨,則直接返回當(dāng)前的bean實(shí)例  
       */
       if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {  
           return beanInstance;  
       }  
       /**如果處理指定名稱(chēng)不是容器的解引用,或者根據(jù)名稱(chēng)獲取的bean實(shí)例對(duì)象是一個(gè)工廠(chǎng)Bean  
       *那么使用工廠(chǎng)Bean創(chuàng)建一個(gè)bean的實(shí)例對(duì)象
       */  
       Object object = null;  
       if (mbd == null) {  
           //從Bean工廠(chǎng)緩存中獲取給定名稱(chēng)的bean實(shí)例對(duì)象  
           object = getCachedObjectForFactoryBean(beanName);  
       }  
       /**如果對(duì)象為null,
       *讓Bean工廠(chǎng)生產(chǎn)給定名稱(chēng)的bean對(duì)象實(shí)例
       */  
       if (object == null) {  
           FactoryBean factory = (FactoryBean) beanInstance;  
           //如果從Bean工廠(chǎng)生產(chǎn)的bean是單例模式唤锉,則進(jìn)行緩存  
           if (mbd == null && containsBeanDefinition(beanName)) {  
               mbd = getMergedLocalBeanDefinition(beanName);  
           }  
           /**如果從容器得到bean定義信息世囊,并且bean定義信息不是虛構(gòu)的,
           *則讓工廠(chǎng)Bean生產(chǎn)bean實(shí)例對(duì)象  
           */
           boolean synthetic = (mbd != null && mbd.isSynthetic());  
           //調(diào)用方法getObjectFromFactoryBean實(shí)現(xiàn)工廠(chǎng)Bean生產(chǎn)bean對(duì)象實(shí)例的過(guò)程  
           object = getObjectFromFactoryBean(factory, beanName, !synthetic);  
       }  
       return object;  
    }

注:
解引用:指所引用對(duì)象的本身數(shù)據(jù)窿祥。
類(lèi)AbstractBeanFactory中方法getObjectFromFactoryBean實(shí)現(xiàn)工廠(chǎng)Bean生產(chǎn)bean對(duì)象實(shí)例的過(guò)程:

//Bean工廠(chǎng)生產(chǎn)bean實(shí)例對(duì)象  
   protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {  
       //如果工廠(chǎng)Bean是單態(tài)模式株憾,并且工廠(chǎng)Bean緩存中存在指定名稱(chēng)的bean實(shí)例對(duì)象  
       if (factory.isSingleton() && containsSingleton(beanName)) {  
           //須多線(xiàn)程同步,防止數(shù)據(jù)不一致  
           synchronized (getSingletonMutex()) {  
               //先從工廠(chǎng)Bean緩存中獲取指定名稱(chēng)的bean實(shí)例對(duì)象  
               Object object = this.factoryBeanObjectCache.get(beanName);  
               /**如果工廠(chǎng)Bean緩存中沒(méi)有指定名稱(chēng)的實(shí)例對(duì)象晒衩,
               *  則生產(chǎn)該實(shí)例對(duì)象
               */
               if (object == null) {  
                   //調(diào)用工廠(chǎng)Bean的getObject方法生產(chǎn)指定bean的實(shí)例對(duì)象  
                   object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);  
                   //將生產(chǎn)的實(shí)例對(duì)象添加到工廠(chǎng)Bean緩存中  
                   this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));  
               }  
               return (object != NULL_OBJECT ? object : null);  
           }  
       }  
       //調(diào)用工廠(chǎng)Bean的getObject方法生產(chǎn)指定bean的實(shí)例對(duì)象  
       else {  
           return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);  
       }  
   }  

方法doGetObjectFromFactoryBean調(diào)用方法getObject生產(chǎn)指定bean的實(shí)例對(duì)象:

  //調(diào)用工廠(chǎng)Bean的getObject方法生產(chǎn)指定bean的實(shí)例對(duì)象  
   private Object doGetObjectFromFactoryBean(  
           final FactoryBean factory, final String beanName, final boolean shouldPostProcess)  
           throws BeanCreationException {  
       Object object;  
       try {  
           if (System.getSecurityManager() != null) {  
               AccessControlContext acc = getAccessControlContext();  
               try {  
                   object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {  
                       public Object run() throws Exception {  
                               //BeanFactory接口實(shí)現(xiàn)類(lèi)創(chuàng)建對(duì)象 
                               return factory.getObject();  
                           }  
                       }, acc);  
               }  
               catch (PrivilegedActionException pae) {  
                   throw pae.getException();  
               }  
           }  
           else {  
               //調(diào)用BeanFactory接口實(shí)現(xiàn)類(lèi)的創(chuàng)建對(duì)象方法  
               object = factory.getObject();  
           }  
       }  
       catch (FactoryBeanNotInitializedException ex) {  
           throw new BeanCurrentlyInCreationException(beanName, ex.toString());  
       }  
       catch (Throwable ex) {  
           throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);  
       }  
       //如果創(chuàng)建出來(lái)的實(shí)例對(duì)象為null嗤瞎,或由于單例對(duì)象正在創(chuàng)建而返回null  
       if (object == null && isSingletonCurrentlyInCreation(beanName)) {  
           throw new BeanCurrentlyInCreationException(  
                   beanName, "FactoryBean which is currently in creation returned null from getObject");  
       }  
       //為已創(chuàng)建的bean實(shí)例對(duì)象添加BeanPostProcessor后置處理器  
       if (object != null && shouldPostProcess) {  
           try {  
               object = postProcessObjectFromFactoryBean(object, beanName);  
           }  
           catch (Throwable ex) {  
               throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);  
           }  
       }  
       return object;  
    }

3. BeanPostProcessor后置處理器的實(shí)現(xiàn)

BeanPostProcessor后置處理器

  1. 名稱(chēng):是一個(gè)監(jiān)聽(tīng)器。
  2. 作用:監(jiān)聽(tīng)容器觸發(fā)的Bean聲明周期事件浸遗。
  3. 影響:后置處理器向容器注冊(cè)以后猫胁,容器中管理的bean就具備了接收IOC容器事件回調(diào)的能力箱亿。
  4. 使用方式:需要提供一個(gè)實(shí)現(xiàn)接口BeanPostProcessor的實(shí)現(xiàn)類(lèi)跛锌,然后在Bean的配置文件中設(shè)置即可。

BeanPostProcessor的源碼如下:

   package org.springframework.beans.factory.config;  
   import org.springframework.beans.BeansException;  
   public interface BeanPostProcessor {  
       //為在bean的初始化前提供回調(diào)入口  
       Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;  
       //為在bean的初始化之后提供回調(diào)入口  
       Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;  
     }

真正實(shí)現(xiàn)創(chuàng)建bean對(duì)象并進(jìn)行依賴(lài)注入的方法是AbstractAutowireCapableBeanFactory類(lèi)的doCreateBean方法:

//真正創(chuàng)建bean的方法  
   protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {  
       //創(chuàng)建bean實(shí)例對(duì)象  
       ……  
       try {  
           //將bean實(shí)例對(duì)象封裝届惋,并且bean定義中配置的屬性值賦值給實(shí)例對(duì)象  
           populateBean(beanName, mbd, instanceWrapper);  
           if (exposedObject != null) {  
               //初始化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);  
           }  
       }  
       ……  
       //為應(yīng)用返回所需要的實(shí)例對(duì)象  
       return exposedObject;  
    }

由上述可知髓帽,為bean實(shí)例對(duì)象添加BeanPostProcessor后置處理器的入口的是initializeBean方法:

   //初始容器創(chuàng)建的bean實(shí)例對(duì)象,為其添加BeanPostProcessor后置處理器  
   protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {  
       if (System.getSecurityManager() != null) {  
           AccessController.doPrivileged(new PrivilegedAction<Object>() {  
               public Object run() {  
                   invokeAwareMethods(beanName, bean);  
                   return null;  
               }  
           }, getAccessControlContext());  
       }  
       else {  
           //為bean實(shí)例對(duì)象包裝相關(guān)屬性  
           invokeAwareMethods(beanName, bean);  
       }  
       Object wrappedBean = bean;  
       //回調(diào)方法的調(diào)用脑豹,為Bean實(shí)例初始化前做一些處理  
       if (mbd == null || !mbd.isSynthetic()) {  
           wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);  
       }  
       /**調(diào)用Bean實(shí)例對(duì)象初始化的方法郑藏,在Spring Bean定義配置,  
       *文件中通過(guò)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;  
   }  

其中必盖,方法applyBeanPostProcessorsBeforeInitialization處理實(shí)例對(duì)象初始化之前

  //調(diào)用BeanPostProcessor后置處理器實(shí)例對(duì)象初始化之前的處理方法  
   public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)  
           throws BeansException {  
       Object result = existingBean;  
       //遍歷容器為所創(chuàng)建的bean添加的所有BeanPostProcessor后置處理器  
       for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {  
           /**調(diào)用Bean實(shí)例所有的后置處理中的初始化前處理方法,  
           *為Bean實(shí)例對(duì)象在初始化之前做一些自定義的處理操作  
           */
           result = beanProcessor.postProcessBeforeInitialization(result, beanName);  
           if (result == null) {  
               return result;  
           }  
       }  
       return result;  
   }  

其中俱饿,方法applyBeanPostProcessorsAfterInitialization處理實(shí)例對(duì)象初始化之后

//調(diào)用BeanPostProcessor后置處理器實(shí)例對(duì)象初始化之后的處理方法  
   public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)  
           throws BeansException {  
       Object result = existingBean;  
       //遍歷容器為所創(chuàng)建的Bean添加的所有BeanPostProcessor后置處理器  
       for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {  
           /**調(diào)用Bean實(shí)例所有的后置處理中的初始化后處理方法歌粥,  
           *為Bean實(shí)例對(duì)象在初始化之后做一些自定義的處理操作 
           */ 
           result = beanProcessor.postProcessAfterInitialization(result, beanName);  
           if (result == null) {  
               return result;  
           }  
       }  
       return result;  
    }

AdvisorAdapterRegistrationManager在Bean對(duì)象初始化后注冊(cè)通知適配器:

//為容器中管理的bean注冊(cè)面向切面編程的通知適配器  
public class AdvisorAdapterRegistrationManager implements BeanPostProcessor {  
   private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();  
   public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {  
       this.advisorAdapterRegistry = advisorAdapterRegistry;  
   }  
   //BeanPostProcessor在bean對(duì)象初始化前的操作  
   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  
       //直接返回容器創(chuàng)建的Bean對(duì)象  
       return bean;  
   }  
   //BeanPostProcessor在bean對(duì)象初始化后的操作  
   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  
       if (bean instanceof AdvisorAdapter){  
              /**如果容器創(chuàng)建的bean實(shí)例對(duì)象是一個(gè)切面通知適配器体捏,
              *則向容器的注冊(cè)
              */
              this.advisorAdapterRegistry.registerAdvisorAdapter((AdvisorAdapter) bean);  
       }  
       return bean;  
   }  
}

未完跟進(jìn)中......(autowiring實(shí)現(xiàn)原理)

4. Spring IOC容器之a(chǎn)utowiring實(shí)現(xiàn)原理

容器提供兩種方式用來(lái)管理bean依賴(lài)關(guān)系:

  1. 顯式管理:通過(guò)BeanDefinition的屬性值和構(gòu)造方法實(shí)現(xiàn)脚祟。
  2. autowiring:自動(dòng)裝配功能,不需對(duì)bean屬性的依賴(lài)關(guān)系做顯式聲明驶俊,只需配置autowiring屬性枣购,容器將通過(guò)反射自動(dòng)查找屬性的類(lèi)型和名稱(chēng)嬉探,之后基于屬性的類(lèi)型或名稱(chēng)自動(dòng)匹配容器中的bean,自動(dòng)完成依賴(lài)注入棉圈。

autowiring自動(dòng)裝配特性: 容器對(duì)Bean的自動(dòng)裝配發(fā)生在容器對(duì)Bean依賴(lài)注入的過(guò)程中涩堤。
而容器對(duì)bean實(shí)例對(duì)象的屬性注入的處理發(fā)生在類(lèi)AbstractAutoWireCapableBeanFactory中的方法populateBean中:

(1) 屬性依賴(lài)注入

類(lèi)AbstractAutoWireCapableBeanFactory的方法populateBean實(shí)現(xiàn)bean屬性依賴(lài)注入的功能:

protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {  
       //獲取bean定義的屬性值  
       PropertyValues pvs = mbd.getPropertyValues();  
       …
       /**對(duì)依賴(lài)注入處理,
       *首先處理autowiring自動(dòng)裝配的依賴(lài)注入  
       */
       if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||  
               mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
           MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  
           //根據(jù)bean名稱(chēng)進(jìn)行autowiring自動(dòng)裝配處理  
           if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {  
               autowireByName(beanName, mbd, bw, newPvs);  
           }  
           //根據(jù)bean類(lèi)型進(jìn)行autowiring自動(dòng)裝配處理  
           if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
               autowireByType(beanName, mbd, bw, newPvs);  
           }  
       }  
       //處理非autowiring的屬性依賴(lài)注入  
        ……  
    }

(2) 根據(jù)bean名稱(chēng)或類(lèi)型進(jìn)行autowiring自動(dòng)依賴(lài)注入:

根據(jù)名稱(chēng)對(duì)屬性進(jìn)行自動(dòng)依賴(lài)注入:

   //根據(jù)名稱(chēng)對(duì)屬性進(jìn)行自動(dòng)依賴(lài)注入  
   protected void autowireByName(  
           String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {  
        //處理 bean對(duì)象中非簡(jiǎn)單屬性
       String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);  
       for (String propertyName : propertyNames) {  
           /**如果容器中包含指定名稱(chēng)的bean  
           *調(diào)用getBean方法向容器索取指定名稱(chēng)的bean實(shí)例分瘾,
           *迭代觸發(fā)對(duì)屬性的初始化和依賴(lài)注入
           */
           if (containsBean(propertyName)) {  
               Object bean = getBean(propertyName);  
               pvs.add(propertyName, bean);  
               //指定名稱(chēng)屬性注冊(cè)依賴(lài)bean名稱(chēng)胎围,屬性依賴(lài)注入  
               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");  
               }  
           }  
       }  
   }  

根據(jù)類(lèi)型對(duì)屬性進(jìn)行自動(dòng)依賴(lài)注入:

 //根據(jù)類(lèi)型對(duì)屬性進(jìn)行自動(dòng)依賴(lài)注入  
   protected void autowireByType(  
           String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {  
       //獲取用戶(hù)定義的類(lèi)型轉(zhuǎn)換器  
       TypeConverter converter = getCustomTypeConverter();  
       if (converter == null) {  
           converter = bw;  
       }  
       //存放解析的要注入的屬性  
       Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);  
         //處理bean對(duì)象中非簡(jiǎn)單屬性
       String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);  
       for (String propertyName : propertyNames) {  
           try {  
               //獲取指定屬性名稱(chēng)的屬性描述器  
               PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);  
               //不對(duì)Object類(lèi)型的屬性進(jìn)行autowiring自動(dòng)依賴(lài)注入  
               if (!Object.class.equals(pd.getPropertyType())) {  
                   MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);  
                   boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());  
                   //創(chuàng)建一個(gè)要被注入的依賴(lài)描述  
                   DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);  
                   /**根據(jù)容器的bean定義解析依賴(lài)關(guān)系,
                   *返回所有要被注入的Bean對(duì)象  
                   */
                   Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);  
                   if (autowiredArgument != null) {  
                       //為屬性賦值所引用的對(duì)象  
                       pvs.add(propertyName, autowiredArgument);  
                   }  
                   for (String autowiredBeanName : autowiredBeanNames) {  
                       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);  
           }  
       }  
    }

真正實(shí)現(xiàn)屬性注入的是類(lèi)DefaultSingletonBeanRegistry的方法registerDependentBean:

   //為指定的bean注入依賴(lài)的bean  
   public void registerDependentBean(String beanName, String dependentBeanName) {  
       //處理bean名稱(chēng) 
       String canonicalName = canonicalName(beanName);  
       /**多線(xiàn)程同步,保證容器內(nèi)數(shù)據(jù)的一致性  
       *根據(jù)bean名稱(chēng)痊远,  
       *在全部依賴(lài)bean名稱(chēng)集合找查找給定名稱(chēng)bean的依賴(lài)bean
       */
       synchronized (this.dependentBeanMap) {  
           Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);  
           if (dependentBeans == null) {  
               dependentBeans = new LinkedHashSet<String>(8);  
               this.dependentBeanMap.put(canonicalName, dependentBeans);  
           }  
           //將bean所依賴(lài)的bean添加到容器的集合中  
           dependentBeans.add(dependentBeanName);  
       }  
         /**指定名稱(chēng)bean的依賴(lài)bean集合找查找給定名稱(chēng)  
         *bean的依賴(lài)bean
         */
       synchronized (this.dependenciesForBeanMap) {  
           Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);  
           if (dependenciesForBean == null) {  
               dependenciesForBean = new LinkedHashSet<String>(8);  
               this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);  
           }  
           //將Bean所依賴(lài)的Bean添加到容器的集合中  
           dependenciesForBean.add(canonicalName);  
       }  
    }

autowiring的實(shí)現(xiàn)過(guò)程:

  1. 通過(guò)對(duì)bean的屬性迭代調(diào)用getBean方法垮抗,完成依賴(lài)bean的初始化和依賴(lài)注入。
  2. 將依賴(lài)bean的屬性引用設(shè)置到被依賴(lài)的bean屬性上碧聪。
  3. 將依賴(lài)bean的名稱(chēng)和被依賴(lài)bean的名稱(chēng)存儲(chǔ)在容器集合中冒版。

autowiring屬性自動(dòng)依賴(lài)注入是一個(gè)很方便的特性,可簡(jiǎn)化開(kāi)發(fā)時(shí)的配置逞姿,但自動(dòng)屬性依賴(lài)注入也有不足辞嗡。
autowiring屬性自動(dòng)依賴(lài)注入的不足:

  1. bean的依賴(lài)關(guān)系在配置文件中并不具有易讀性,不利于維護(hù)造成一定困難滞造。
  2. 將依賴(lài)注入交給容器自動(dòng)執(zhí)行续室,若配置不當(dāng),后果無(wú)法評(píng)估谒养。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挺狰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子买窟,更是在濱河造成了極大的恐慌丰泊,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件始绍,死亡現(xiàn)場(chǎng)離奇詭異瞳购,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)亏推,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)学赛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人吞杭,你說(shuō)我怎么就攤上這事盏浇。” “怎么了篇亭?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵缠捌,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我译蒂,道長(zhǎng)曼月,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任柔昼,我火速辦了婚禮哑芹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捕透。我一直安慰自己聪姿,他們只是感情好碴萧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著末购,像睡著了一般破喻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盟榴,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天曹质,我揣著相機(jī)與錄音,去河邊找鬼擎场。 笑死羽德,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的迅办。 我是一名探鬼主播宅静,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼站欺!你這毒婦竟也來(lái)了姨夹?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤镊绪,失蹤者是張志新(化名)和其女友劉穎匀伏,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蝴韭,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年熙侍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了榄鉴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛉抓,死狀恐怖庆尘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情巷送,我是刑警寧澤驶忌,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站笑跛,受9級(jí)特大地震影響付魔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜飞蹂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一几苍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陈哑,春花似錦妻坝、人聲如沸伸眶。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)厘贼。三九已至,卻和暖如春圣拄,著一層夾襖步出監(jiān)牢的瞬間涂臣,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工售担, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赁遗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓族铆,卻偏偏與公主長(zhǎng)得像岩四,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哥攘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

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