在Bean的屬性被Spring容器設定之後,您還有機會自訂一些對Bean的修正,您可以實作org.springframework.beans.factory.config.BeanPostProcessor介面:
package org.springframework.beans.factory.config;
public interface BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException;
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException;
}
public interface BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException;
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException;
}
postProcessBeforeInitialization()方法會在Bean初始化動作之前(例如InitializingBean的 afterPropertiesSet()方法或自定義的init方法)被呼叫,而postProcessAfterInitialization()方法會在Bean初始化之後立即被呼叫。
舉個例子來說,您可以實作一個大寫修正器,對於String型態的Bean屬性,無論在定義檔中是設定為大寫或小寫,在Bean屬性設定之後,您可以在大寫修正器中將所有的String改為大寫,例如:
- UpperCaseModifier.java
package onlyfun.caterpillar;
import java.lang.reflect.Field;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class UpperCaseModifier implements BeanPostProcessor {
public Object postProcessBeforeInitialization(
Object bean, String name) throws BeansException {
Field[] fields = bean.getClass().getDeclaredFields();
for(int i = 0; i < fields.length; i++) {
if(fields[i].getType().equals(String.class)) {
fields[i].setAccessible(true);
try {
String original = (String) fields[i].get(bean);
fields[i].set(bean, original.toUpperCase());
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return bean;
}
public Object postProcessAfterInitialization(
Object bean, String name) throws BeansException {
return bean;
}
}
假設您定義了這麼一個Bean類別:
- HelloBean.java
package onlyfun.caterpillar;
public class HelloBean {
private String helloWord;
public HelloBean() {
}
public void setHelloWord(String helloWord) {
this.helloWord = helloWord;
}
public String getHelloWord() {
return helloWord;
}
}
ApplicationContext會自動偵測您是否在定義檔中定義了實作BeanPostProcessor介面的類別,例如:
- beans-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="upperCaseModifier"
class="onlyfun.caterpillar.UpperCaseModifier"/>
<bean id="helloBean" class="onlyfun.caterpillar.HelloBean">
<property name="helloWord">
<value>Hello!</value>
</property>
</bean>
</beans>
Spring容器會在每一個Bean被初始化之前之後分別呼叫upperCaseModifier的 postProcessBeforeInitialization()方法與postProcessAfterInitialization()方法,以 對Bean進行指定的相關修正,可以實際來看看以下的測試程式:
- SpringDemo.java
package onlyfun.caterpillar;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class SpringDemo {
public static void main(String[] args) {
ApplicationContext context =
new FileSystemXmlApplicationContext("beans-config.xml");
HelloBean hello =
(HelloBean) context.getBean("helloBean");
System.out.println(hello.getHelloWord());
}
}
執行結果如下:
HELLO!
雖然您在定義檔中的helloBean之helloWord屬性是設定小寫字母,但upperCaseModifier將之改為大寫字母了。