BeanPostProcessor(Bean後置處理器)常用在對bean內部的值進行修改;實現Bean的動態代理等。
BeanFactoryPostProcessor和BeanPostProcessor都是spring初始化bean時對外暴露的擴充點。但它們有什麼區別呢?
由《理解Bean生命週期》的圖可知:BeanFactoryPostProcessor是生命週期中最早被調用的,遠遠早於BeanPostProcessor。它在spring容器載入了bean的定義檔案之後,在bean執行個體化之前執行的。也就是說,Spring允許BeanFactoryPostProcessor在容器建立bean之前讀取bean配置中繼資料,並可進行修改。例如增加bean的屬性和值,重新設定bean是否作為自動裝配的侯選者,重設bean的依賴項等等。
在srping設定檔中可以同時配置多個BeanFactoryPostProcessor,並通過在xml中註冊時設定’order’屬性來控制各個BeanFactoryPostProcessor的執行次序。
BeanFactoryPostProcessor介面定義如下:
public interface BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;}
介面只有一個方法postProcessBeanFactory。該方法的參數是ConfigurableListableBeanFactory類型,實際開發中,我們常使用它的getBeanDefinition()方法擷取某個bean的中繼資料定義:BeanDefinition。它有這些方法:
看個例子:
設定檔中定義了一個bean:
<bean id="messi" class="twm.spring.LifecycleTest.footballPlayer"> <property name="name" value="Messi"></property> <property name="team" value="Barcelona"></property></bean>
建立類beanFactoryPostProcessorImpl,實現介面BeanFactoryPostProcessor:
public class beanFactoryPostProcessorImpl implements BeanFactoryPostProcessor{ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("beanFactoryPostProcessorImpl"); BeanDefinition bdefine=beanFactory.getBeanDefinition("messi"); System.out.println(bdefine.getPropertyValues().toString()); MutablePropertyValues pv = bdefine.getPropertyValues(); if (pv.contains("team")) { PropertyValue ppv= pv.getPropertyValue("name"); TypedStringValue obj=(TypedStringValue)ppv.getValue(); if(obj.getValue().equals("Messi")){ pv.addPropertyValue("team", "阿根延"); } } bdefine.setScope(BeanDefinition.SCOPE_PROTOTYPE); }}
調用類:
public static void main(String[] args) throws Exception { ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); footballPlayer obj = ctx.getBean("messi",footballPlayer.class); System.out.println(obj.getTeam());}
輸出:
PropertyValues: length=2; bean property ‘name’; bean property ‘team’
阿根延
在《PropertyPlaceholderConfigurer應用》提到的PropertyPlaceholderConfigurer這個類就是BeanFactoryPostProcessor介面的一個實現。它會在容器建立bean之前,將類定義中的預留位置(諸如${jdbc.url})用properties檔案對應的內容進行替換。