BeanPostProcessor 介面定義兩個回調:
postProcessBeforeInitialization:Bean 初始化方法(如 @PostConstruct、init-method)執行前調用。postProcessAfterInitialization:初始化方法執行後調用,可修改或替換 Bean 實例。實現類註冊到容器後,所有 Bean 都會經過這兩個回調,故需在方法內判斷目標 Bean(按類型或名稱)。
| 容器類型 | 註冊方式 |
|---|---|
| BeanFactory | 程式化調用 addBeanPostProcessor(processor) |
| ApplicationContext | XML 宣告 <bean class="..."/>,容器自動識別並註冊 |
實作 Ordered 介面,設定 order 屬性值越小優先級越高。
public class Animal {
private String name;
private int age;
public String speak() { return "我的名字是:" + name + ",年齡是:" + age + "!"; }
// getter/setter 省略
}
public class BeanPost implements BeanPostProcessor {
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof Animal) {
Animal a = (Animal) bean;
a.setAge(50);
a.setName("猴子");
return a;
}
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Before init: " + beanName);
return bean;
}
}
<bean id="animal" class="ioc.test.Animal">
<property name="age" value="5"/>
<property name="name" value="豬"/>
</bean>
<bean id="beanPost" class="ioc.test.BeanPost"/>
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Animal animal = (Animal) ac.getBean("animal");
System.out.println(animal.speak());
// 輸出:我的名字是:猴子,年齡是:50!
配置文件注入的「豬、5歲」被後處理器改為「猴子、50歲」,驗證機制生效。
null 會導致後續獲取失敗。postProcessBeforeInitialization 中依賴 Bean 的初始化狀態(如 @Autowired 欄位尚未填充)。