使用BeanPostProcessor接口对受管Bean进行预处理
有時候,我們希望在Spring IoC容器初始化受管Bean之前、屬性設置之后對該Bean先做一些預處理,或者在容器銷毀受管Bean之前自己釋放資源。那么該如何實現呢?Spring IoC為我們提供了多種方法來實現受管Bean的預處理和后處理。
在Spring中定義了BeanPostProcessors接口,代碼如下:
Java代碼??
package?org.springframework.beans.factory.config;??
??
import?org.springframework.beans.BeansException;??
??
public?interface?BeanPostProcessor?{??
??
Object?postProcessBeforeInitialization(Object?bean,String?BeanName)throws?BeansException;??
??
Object?postProcessAfterInitialization(Object?bean,String?BeanName)throws?BeansException;???
}??
??
如果這個接口的某個實現類被注冊到某個容器,那么該容器的每個受管Bean在調用初始化方法之前,都會獲得該接口實現類的一個回調。容器調用接口定義的方法時會將該受管Bean的實例和名字通過參數傳入方法,進過處理后通過方法的返回值返回給容器。根據這個原理,我們就可以很輕松的自定義受管Bean。
上面提到過,要使用BeanPostProcessor回調,就必須先在容器中注冊實現該接口的類,那么如何注冊呢?BeanFactory和ApplicationContext容器的注冊方式不大一樣:若使用BeanFactory,則必須要顯示的調用其addBeanPostProcessor()方法進行注冊,參數為BeanPostProcessor實現類的實例;如果是使用ApplicationContext,那么容器會在配置文件在中自動尋找實現了BeanPostProcessor接口的Bean,然后自動注冊,我們要做的只是配置一個BeanPostProcessor實現類的Bean就可以了。
注意,假如我們使用了多個的BeanPostProcessor的實現類,那么如何確定處理順序呢?其實只要實現Ordered接口,設置order屬性就可以很輕松的確定不同實現類的處理順序了。
例程3.5展示了如何使用BeanPostProcessor回調接口。創建Java工程,為其添加Spring開發能力后,創建ioc.test包。再創建一個名字為Animal的Bean,添加name、age成員和speak()方法。代碼如下:
Java代碼??
package?ioc.test;??
??
public?class?Animal?{??
??
private?String?name;??
??
private?int?age;??
??
public?String?speak(){??
return?"我的名字是:"+this.name+",年齡是:"+this.age+"!\n";??
}??
//Geter和Seter省略??
}??
?
創建一個BeanPost類,實現BeanPostProcessor接口。在其postProcessAfterInitialization()方法中修改通過參數傳入的受管Bean,然后返回。由于它處理容器中的每一個Bean,因此在修改前,應判斷Bean是否為我們要處理的Bean。可以通過傳入Bean的類型判定,也可以通過傳入Bean的名字判定。代碼如下:
Java代碼??
package?ioc.test;??
??
//Import省略??
??
public?class?BeanPost?implements?BeanPostProcessor?{??
??
public?Object?postProcessAfterInitialization(Object?bean,?String?beanName)?throws?BeansException?{??
??
System.out.println("BeanPostProcessor.postProcessAfterInitialization?正在預處理!");??
??
if?((bean?instanceof?Animal))?{??
??
Animal?animal?=?(Animal)?bean;??
??
animal.setAge(50);??
??
animal.setName("猴子");??
??
return?bean;??
??
}??
??
return?bean;??
}??
??
public?Object?postProcessBeforeInitialization(Object?bean,?String?beanName)?throws?BeansException?{??
??
System.out.println("BeanPostProcessor.postProcessBeforeInitialization?正在預處理!");??
??
return?bean;??
??
}??
}??
?
定義好Animal Bean,為其屬性隨便注入一個值,再定義一個Bean,class為BeanPost類。代碼如下:
Java代碼??
<?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-2.5.xsd">??
<bean?id="animal"?class="ioc.test.Animal">??
<property?name="age"??value="5"></property>??
<property?name="name"?value="豬"></property>??
</bean>??
<bean?id="beanPost"?class="ioc.test.BeanPost"></bean>??
</beans>??
?
?
?
最后創建TestMain類輸出結果,代碼如下:
Java代碼??
package?ioc.test;??
??
//Import省略??
??
public?class?TestMain?{??
??
public?static?void?main(String[]?args)?{??
??
ApplicationContext?ac?=?new?ClassPathXmlApplicationContext("applicationContext.xml");??
Animal?animal?=?(Animal)ac.getBean("animal");??
System.out.println(animal.speak());??????
??
}??
}??
?
運行后輸出結果如下:
?
運行結果
可以看到,輸出結果并不是我們在配置文件中注入的值,這說明BeanPost已經成功的修改了目標Bean。
轉載于:https://my.oschina.net/liangzhenghui/blog/209457
總結
以上是生活随笔為你收集整理的使用BeanPostProcessor接口对受管Bean进行预处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 写一个函数,使给定的一个二维数组(3×3
- 下一篇: 关于多层html标签嵌套引起CSS冲突问