使用BeanPostProcessor接口对受管Bean进行预处理
有時(shí)候,我們希望在Spring IoC容器初始化受管Bean之前、屬性設(shè)置之后對(duì)該Bean先做一些預(yù)處理,或者在容器銷毀受管Bean之前自己釋放資源。那么該如何實(shí)現(xiàn)呢?Spring IoC為我們提供了多種方法來(lái)實(shí)現(xiàn)受管Bean的預(yù)處理和后處理。
在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;???
}??
??
如果這個(gè)接口的某個(gè)實(shí)現(xiàn)類被注冊(cè)到某個(gè)容器,那么該容器的每個(gè)受管Bean在調(diào)用初始化方法之前,都會(huì)獲得該接口實(shí)現(xiàn)類的一個(gè)回調(diào)。容器調(diào)用接口定義的方法時(shí)會(huì)將該受管Bean的實(shí)例和名字通過(guò)參數(shù)傳入方法,進(jìn)過(guò)處理后通過(guò)方法的返回值返回給容器。根據(jù)這個(gè)原理,我們就可以很輕松的自定義受管Bean。
上面提到過(guò),要使用BeanPostProcessor回調(diào),就必須先在容器中注冊(cè)實(shí)現(xiàn)該接口的類,那么如何注冊(cè)呢?BeanFactory和ApplicationContext容器的注冊(cè)方式不大一樣:若使用BeanFactory,則必須要顯示的調(diào)用其addBeanPostProcessor()方法進(jìn)行注冊(cè),參數(shù)為BeanPostProcessor實(shí)現(xiàn)類的實(shí)例;如果是使用ApplicationContext,那么容器會(huì)在配置文件在中自動(dòng)尋找實(shí)現(xiàn)了BeanPostProcessor接口的Bean,然后自動(dòng)注冊(cè),我們要做的只是配置一個(gè)BeanPostProcessor實(shí)現(xiàn)類的Bean就可以了。
注意,假如我們使用了多個(gè)的BeanPostProcessor的實(shí)現(xiàn)類,那么如何確定處理順序呢?其實(shí)只要實(shí)現(xiàn)Ordered接口,設(shè)置order屬性就可以很輕松的確定不同實(shí)現(xiàn)類的處理順序了。
例程3.5展示了如何使用BeanPostProcessor回調(diào)接口。創(chuàng)建Java工程,為其添加Spring開(kāi)發(fā)能力后,創(chuàng)建ioc.test包。再創(chuàng)建一個(gè)名字為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省略??
}??
?
創(chuàng)建一個(gè)BeanPost類,實(shí)現(xiàn)BeanPostProcessor接口。在其postProcessAfterInitialization()方法中修改通過(guò)參數(shù)傳入的受管Bean,然后返回。由于它處理容器中的每一個(gè)Bean,因此在修改前,應(yīng)判斷Bean是否為我們要處理的Bean。可以通過(guò)傳入Bean的類型判定,也可以通過(guò)傳入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?正在預(yù)處理!");??
??
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?正在預(yù)處理!");??
??
return?bean;??
??
}??
}??
?
定義好Animal Bean,為其屬性隨便注入一個(gè)值,再定義一個(gè)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>??
?
?
?
最后創(chuàng)建TestMain類輸出結(jié)果,代碼如下:
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());??????
??
}??
}??
?
運(yùn)行后輸出結(jié)果如下:
?
運(yùn)行結(jié)果
可以看到,輸出結(jié)果并不是我們?cè)谂渲梦募凶⑷氲闹?#xff0c;這說(shuō)明BeanPost已經(jīng)成功的修改了目標(biāo)Bean。
轉(zhuǎn)載于:https://my.oschina.net/liangzhenghui/blog/209457
總結(jié)
以上是生活随笔為你收集整理的使用BeanPostProcessor接口对受管Bean进行预处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 写一个函数,使给定的一个二维数组(3×3
- 下一篇: java ui线程_UI线程异常处理方法