1. 程式人生 > >org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator

org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator

Spring提供了很多擴充套件介面,BeanPostProcessor介面和InstantiationAwareBeanPostProcessor介面就是其中兩個。

BeanPostProcessor

BeanPostProcessor介面作用是:如果我們需要在Spring容器完成Bean的例項化、配置和其他的初始化前後新增一些自己的邏輯處理,我們就可以定義一個或者多個BeanPostProcessor介面的實現,然後註冊到容器中。

Spring中Bean的例項化過程圖示:

由上圖可以看到,Spring中的BeanPostProcessor在例項化過程處於的位置,BeanPostProcessor介面有兩個方法需要實現:postProcessBeforeInitialization和postProcessAfterInitialization,

Java程式碼  收藏程式碼
  1. import org.springframework.beans.factory.config.BeanPostProcessor;  
  2. publicclass MyBeanPostProcessor implements BeanPostProcessor {  
  3.      public MyBeanPostProcessor() {  
  4.         super();  
  5.         System.out.println("這是BeanPostProcessor實現類構造器!!");          
  6.      }  
  7.      @Override
  8.      public
     Object postProcessAfterInitialization(Object bean, String arg1)  
  9.              throws BeansException {  
  10.          System.out.println("bean處理器:bean建立之後..");  
  11.          return bean;  
  12.      }  
  13.      @Override
  14.      public Object postProcessBeforeInitialization(Object bean, String arg1)  
  15.              throws BeansException {  
  16.          System.out.println("bean處理器:bean建立之前..");  
  17.          return bean;  
  18.      }  
  19.  }  

BeanPostProcessor介面定義如下:

Java程式碼  收藏程式碼
  1. publicinterface BeanPostProcessor {  
  2.     /** 
  3.      * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean 
  4.      * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} 
  5.      * or a custom init-method). The bean will already be populated with property values.    
  6.      */
  7. //例項化、依賴注入完畢,在呼叫顯示的初始化之前完成一些定製的初始化任務
  8.     Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;  
  9.     /** 
  10.      * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean 
  11.      * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}   
  12.      * or a custom init-method). The bean will already be populated with property values.       
  13.      */
  14. //例項化、依賴注入、初始化完畢時執行
  15.     Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;  
  16. }  

由方法名字也可以看出,前者在例項化及依賴注入完成後、在任何初始化程式碼(比如配置檔案中的init-method)呼叫之前呼叫;後者在初始化程式碼呼叫之後呼叫。

注意:

1、介面中的兩個方法都要將傳入的bean返回,而不能返回null,如果返回的是null那麼我們通過getBean方法將得不到目標。

2、BeanFactory和ApplicationContext對待bean後置處理器稍有不同。ApplicationContext會自動檢測在配置檔案中實現了BeanPostProcessor介面的所有bean,並把它們註冊為後置處理器,然後在容器建立bean的適當時候呼叫它,因此部署一個後置處理器同部署其他的bean並沒有什麼區別。而使用BeanFactory實現的時候,bean 後置處理器必須通過程式碼顯式地去註冊,在IoC容器繼承體系中的ConfigurableBeanFactory介面中定義了註冊方法:

Java程式碼  收藏程式碼
  1. /**  
  2.  * Add a new BeanPostProcessor that will get applied to beans created  
  3.  * by this factory. To be invoked during factory configuration.  
  4.  * <p>Note: Post-processors submitted here will be applied in the order of  
  5.  * registration; any ordering semantics expressed through implementing the  
  6.  * {@link org.springframework.core.Ordered} interface will be ignored. Note  
  7.  * that autodetected post-processors (e.g. as beans in an ApplicationContext)  
  8.  * will always be applied after programmatically registered ones.  
  9.  * @param beanPostProcessor the post-processor to register  
  10.  */
  11. void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);   

另外,不要將BeanPostProcessor標記為延遲初始化。因為如果這樣做,Spring容器將不會註冊它們,自定義邏輯也就無法得到應用。假如你在<beans />元素的定義中使用了'default-lazy-init'屬性,請確信你的各個BeanPostProcessor標記為'lazy-init="false"'。

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor是BeanPostProcessor的子介面,可以在Bean生命週期的另外兩個時期提供擴充套件的回撥介面,即例項化Bean之前(呼叫postProcessBeforeInstantiation方法)和例項化Bean之後(呼叫postProcessAfterInstantiation方法),該介面定義如下:
Java程式碼  收藏程式碼
  1. package org.springframework.beans.factory.config;    
  2. import java.beans.PropertyDescriptor;    
  3. import org.springframework.beans.BeansException;    
  4. import org.springframework.beans.PropertyValues;    
  5. publicinterface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {    
  6.     Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;    
  7.     boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;    
  8.     PropertyValues postProcessPropertyValues(    
  9.             PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)    
  10.             throws BeansException;    
  11. }  
 其使用方法與上面介紹的BeanPostProcessor介面類似,只時回撥時機不同。 如果是使用ApplicationContext來生成並管理Bean的話則稍有不同,使用ApplicationContext來生成及管理Bean例項的話,在執行BeanFactoryAware的setBeanFactory()階段後,若Bean類上有實現org.springframework.context.ApplicationContextAware介面,則執行其setApplicationContext()方法,接著才執行BeanPostProcessors的ProcessBeforeInitialization()及之後的流程。