BeanPostProcessor接口作用:
如果我們想在Spring容器中完成bean實例化漫玄、配置以及其他初始化方法前后要添加一些自己邏輯處理压彭。我們需要定義一個或多個BeanPostProcessor接口實現(xiàn)類,然后注冊到Spring IoC容器中壮不。
package com.test.spring;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* bean后置處理器
* @author zss
*
*/
public class PostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean,
String beanName) throws BeansException {
if ("narCodeService".equals(beanName)) {//過濾掉bean實例ID為narCodeService
return bean;
}
System.out.println("后置處理器處理bean=【"+beanName+"】開始");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
if ("narCodeService".equals(beanName)) {
return bean;
}
System.out.println("后置處理器處理bean=【"+beanName+"】完畢!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return bean;
}
}
注意:接口中兩個方法不能返回null询一,如果返回null那么在后續(xù)初始化方法將報空指針異嘲┐唬或者通過getBean()方法獲取不到bena實例對象
因為后置處理器從Spring IoC容器中取出bean實例對象沒有再次放回IoC容器中
## BeanPostProcessor API:
public interface BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
*/
//實例化菱阵、依賴注入完畢,在調(diào)用顯示的初始化之前完成一些定制的初始化任務(wù)
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
*/
//實例化晴及、依賴注入、初始化完畢時執(zhí)行
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
由API可以看出:
1:后置處理器的postProcessorBeforeInitailization方法是在bean實例化虑稼,依賴注入之后及自定義初始化方法(例如:配置文件中bean標簽添加init-method屬性指定Java類中初始化方法、
@PostConstruct注解指定初始化方法蛛倦,Java類實現(xiàn)InitailztingBean接口)之前調(diào)用
2:后置處理器的postProcessorAfterInitailization方法是在bean實例化、依賴注入及自定義初始化方法之后調(diào)用
注意:
1.BeanFactory和ApplicationContext兩個容器對待bean的后置處理器稍微有些不同溯壶。ApplicationContext容器會自動檢測Spring配置文件中那些bean所對應(yīng)的Java類實現(xiàn)了BeanPostProcessor
接口,并自動把它們注冊為后置處理器且改。在創(chuàng)建bean過程中調(diào)用它們,所以部署一個后置處理器跟普通的bean沒有什么太大區(qū)別钾虐。
2.BeanFactory容器注冊bean后置處理器時必須通過代碼顯示的注冊笋庄,在IoC容器繼承體系中的ConfigurableBeanFactory接口中定義了注冊方法
/**
* Add a new BeanPostProcessor that will get applied to beans created
* by this factory. To be invoked during factory configuration.
* <p>Note: Post-processors submitted here will be applied in the order of
* registration; any ordering semantics expressed through implementing the
* {@link org.springframework.core.Ordered} interface will be ignored. Note
* that autodetected post-processors (e.g. as beans in an ApplicationContext)
* will always be applied after programmatically registered ones.
* @param beanPostProcessor the post-processor to register
*/
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
Spring如何調(diào)用多個BeanPostProcessor實現(xiàn)類:
我們可以在Spring配置文件中添加多個BeanPostProcessor(后置處理器)接口實現(xiàn)類,在默認情況下Spring容器會根據(jù)后置處理器的定義順序來依次調(diào)用菌仁。
在Spring機制中可以指定后置處理器調(diào)用順序,通過讓BeanPostProcessor接口實現(xiàn)類實現(xiàn)Ordered接口getOrder方法济丘,該方法返回一整數(shù),默認值為 0摹迷,優(yōu)先級最高,值越大優(yōu)先級越低