1後置處理器是什麼?
一個類,實現了接口BeanPostProcessor 定義的兩個方法,這兩個方法分別是:postProcessBeforeInitialization和postProcessAfterInitialization,顧名思義,就是分別在bean的init-method前後進行分別執行這兩個方法。
多後置處理器的有序性的
bean在使用的過程中可以經過多個後置預處理的處理,但是,一般情況下,多個實現後置處理器接口的類是有先後順序的,爲了讓IOC明白後置處理器之間的先後順序,類還要實現Ordered接口,通過接口裏的order屬性來控制後處理器的先後順序,默認爲0,爲最高優先級。
同一個容器中的後置處理器是通用的
一個context中的後置處理器實現類不是針對某一個的bean,這個context中的所有bean的產生過程都回去調用這個後置處理器,爲了有針對性,可以通過bean的id來執行特異話的操作。
2 後置處理器實現類
BeanPostProcessor 接口源碼
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
可見,返回值必須爲非null,且必須是Object類型,和從context中get出來的一致。由於是有默認實現,因此,不是必須要重寫方法的。現在看一個後處理器類的實例:
package 後置處理器;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class PostProcessorExample implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("chinese".equals(beanName)) {
System.out.println("後置處理器,初始化前處理的bean的id是:" + beanName);
} else {
System.out.println("後置處理器,初始化前處理的bean的id是:" + beanName);
}
return bean;
}
}
通過beanName對處理的bean進行針對性的區分、處理。
3 後置處理器實現類bean配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="chinese" class="初始化和銷燬回調.Chinese">
</bean>
<bean id="american" class="初始化和銷燬回調.American">
</bean>
<bean id="beanPostProcessor" class="後置處理器.PostProcessorExample">
</bean>
</beans>
4 運行調用
主類
package 後置處理器;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class PostProcessorExample implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("chinese".equals(beanName)) {
System.out.println("後置處理器,初始化前處理的bean的id是:" + beanName);
} else {
System.out.println("後置處理器,初始化前處理的bean的id是:" + beanName);
}
return bean;
}
}
其中America類實現了InitializingBean, DisposableBean這兩個接口,xml配置元數據中不配置也自帶初始化和銷燬方法,Chinese完全沒有指定初始化和銷燬方法,因此,控制檯輸出是:
後置處理器,初始化前處理的bean的id是:chinese
後置處理器,初始化前處理的bean的id是:american
American 初始化回調函數
American 銷燬回調函數
5多後置處理器調用
最理想的情況下,讓實現類去實現Ordered最理想的,但是,在默認情況下,Spring容器會根據後置處理器的定義順序來依次調用,比如:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- bean定義 -->
<bean id="narCodeService" class="com.test.service.impl.NarCodeServiceImpl">
</bean>
<bean id="postProcessor" class="com.test.spring.PostProcessor"/>
<bean id="postProcessorB" class="com.test.spring.PostProcessorB"/>
</beans>
在bean配置元數據,就回讓IOC容器最後再調用B後置處理器。但是!官方還是建議去實現順序接口來顯式定義的後置處理器的實現順序!