Spring中的后置處理器BeanPostProcessor詳解
BeanPostProcessor接口作用:
如果我們想在Spring容器中完成bean實(shí)例化、配置以及其他初始化方法前后要添加一些自己邏輯處理。我們需要定義一個(gè)或多個(gè)BeanPostProcessor接口實(shí)現(xiàn)類,然后注冊(cè)到Spring IoC容器中。
package com.test.spring; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * bean后置處理器 * @author zss * */ public class PostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("narCodeService".equals(beanName)) {//過濾掉bean實(shí)例ID為narCodeService return bean; } System.out.println("后置處理器處理bean=【"+beanName+"】開始"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ("narCodeService".equals(beanName)) { return bean; } System.out.println("后置處理器處理bean=【"+beanName+"】完畢!"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return bean; } }
注意:接口中兩個(gè)方法不能返回null,如果返回null那么在后續(xù)初始化方法將報(bào)空指針異?;蛘咄ㄟ^getBean()方法獲取不到bena實(shí)例對(duì)象,因?yàn)楹笾锰幚砥鲝腟pring IoC容器中取出bean實(shí)例對(duì)象沒有再次放回IoC容器中!
將Spring的后置處理器PostProcessor配置到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"> <!-- 定義一個(gè)bean --> <bean id="narCodeService" class="com.test.service.impl.NarCodeServiceImpl"> </bean> <bean id="beanLifecycle" class="com.test.spring.BeanLifecycle" init-method="init" destroy-method="close"> <property name="name" value="張三"></property> <property name="sex" value="男"></property> </bean> <!-- Spring后置處理器 --> <bean id="postProcessor" class="com.test.spring.PostProcessor"/> </beans>
BeanPostProcessor API:
public interface BeanPostProcessor { //實(shí)例化、依賴注入完畢,在調(diào)用顯示的初始化之前完成一些定制的初始化任務(wù) Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; //實(shí)例化、依賴注入、初始化完畢時(shí)執(zhí)行 Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
由API可以看出:
1:后置處理器的postProcessorBeforeInitailization方法是在bean實(shí)例化,依賴注入之后及自定義初始化方法(例如:配置文件中bean標(biāo)簽添加init-method屬性指定Java類中初始化方法、
@PostConstruct注解指定初始化方法,Java類實(shí)現(xiàn)InitailztingBean接口)之前調(diào)用
2:后置處理器的postProcessorAfterInitailization方法是在bean實(shí)例化、依賴注入及自定義初始化方法之后調(diào)用
注意:
1.BeanFactory和ApplicationContext兩個(gè)容器對(duì)待bean的后置處理器稍微有些不同。ApplicationContext容器會(huì)自動(dòng)檢測(cè)Spring配置文件中那些bean所對(duì)應(yīng)的Java類實(shí)現(xiàn)了BeanPostProcessor
接口,并自動(dòng)把它們注冊(cè)為后置處理器。在創(chuàng)建bean過程中調(diào)用它們,所以部署一個(gè)后置處理器跟普通的bean沒有什么太大區(qū)別。
2.BeanFactory容器注冊(cè)bean后置處理器時(shí)必須通過代碼顯示的注冊(cè),在IoC容器繼承體系中的ConfigurableBeanFactory接口中定義了注冊(cè)方法
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
Spring如何調(diào)用多個(gè)BeanPostProcessor實(shí)現(xiàn)類:
我們可以在Spring配置文件中添加多個(gè)BeanPostProcessor(后置處理器)接口實(shí)現(xiàn)類,在默認(rèn)情況下Spring容器會(huì)根據(jù)后置處理器的定義順序來依次調(diào)用。
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>
BeanPostProcessor實(shí)現(xiàn)類:
package com.test.spring; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * bean后置處理器 * @author zss * */ public class PostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("后置處理器處理bean=【"+beanName+"】開始"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("后置處理器處理bean=【"+beanName+"】完畢!"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return bean; } } ---------------------------------------------------------------------------------------------------------------------------------------- package com.test.spring; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class PostProcessorB implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("后置處理器開始調(diào)用了"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("后置處理器調(diào)用結(jié)束了"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return bean; } }
Test case:
package com.test.spring; import org.junit.Before; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class T { AbstractApplicationContext applicationcontext=null; @Before public void before() { System.out.println("》》》Spring ApplicationContext容器開始初始化了......"); applicationcontext= new ClassPathXmlApplicationContext(new String[]{"test1-service.xml"}); System.out.println("》》》Spring ApplicationContext容器初始化完畢了......"); } @Test public void test() { applicationcontext.registerShutdownHook(); } }
測(cè)試結(jié)果:
》》》Spring ApplicationContext容器開始初始化了...... 2017-03-19 10:50:29 INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9: startup date [Sun Mar 19 10:50:29 CST 2017]; root of context hierarchy 2017-03-19 10:50:29 INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [test1-service.xml] 后置處理器處理bean=【narCodeService】開始 后置處理器開始調(diào)用了 后置處理器處理bean=【narCodeService】完畢! 后置處理器調(diào)用結(jié)束了 》》》Spring ApplicationContext容器初始化完畢了...... 2017-03-19 10:50:34 INFO:ClassPathXmlApplicationContext-Closing org.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9: startup date [Sun Mar 19 10:50:29 CST 2017]; root of context hierarchy
在Spring機(jī)制中可以指定后置處理器調(diào)用順序,通過讓BeanPostProcessor接口實(shí)現(xiàn)類實(shí)現(xiàn)Ordered接口getOrder方法,該方法返回一整數(shù),默認(rèn)值為 0,優(yōu)先級(jí)最高,值越大優(yōu)先級(jí)越低
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Spring?BeanPostProcessor后處理器源碼解析
- 關(guān)于Spring BeanPostProcessor的執(zhí)行順序
- Spring BeanPostProcessor(后置處理器)的用法
- SpringBoot之通過BeanPostProcessor動(dòng)態(tài)注入ID生成器案例詳解
- Spring容器的創(chuàng)建過程之如何注冊(cè)BeanPostProcessor詳解
- 詳解使用Spring的BeanPostProcessor優(yōu)雅的實(shí)現(xiàn)工廠模式
- Spring BeanPostProcessor接口使用詳解
- 解析Java的Spring框架的BeanPostProcessor發(fā)布處理器
- spring中BeanPostProcessor的作用和使用注意事項(xiàng)
相關(guān)文章
java項(xiàng)目構(gòu)建Gradle的使用教程
這篇文章主要為大家介紹了java項(xiàng)目構(gòu)建Gradle的使用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03SpringMVC框架實(shí)現(xiàn)上傳圖片的示例代碼
本篇文章主要介紹了SpringMVC框架實(shí)現(xiàn)上傳圖片的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09Spring實(shí)現(xiàn)動(dòng)態(tài)修改時(shí)間參數(shù)并手動(dòng)開啟關(guān)停操作
spring實(shí)現(xiàn)定時(shí)任務(wù)的方式有三種,分別是java自帶的timer類、spring task和quartz三種。本文只介紹spring自帶的task和第三方quartz,感興趣的朋友參考下吧2017-09-09Springboot啟動(dòng)同時(shí)創(chuàng)建數(shù)據(jù)庫和表實(shí)現(xiàn)方法
這篇文章主要介紹了Springboot啟動(dòng)同時(shí)創(chuàng)建數(shù)據(jù)庫和表,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-01-01java web實(shí)現(xiàn)簡(jiǎn)易收費(fèi)站
這篇文章主要為大家詳細(xì)介紹了java web實(shí)現(xiàn)簡(jiǎn)易收費(fèi)站,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一2020-11-11java使用Hex編碼解碼實(shí)現(xiàn)Aes加密解密功能示例
這篇文章主要介紹了java使用Hex編碼解碼實(shí)現(xiàn)Aes加密解密功能,結(jié)合完整實(shí)例形式分析了Aes加密解密功能的定義與使用方法,需要的朋友可以參考下2017-01-01SpringBoot @ModelAttribute使用場(chǎng)景分析
這篇文章主要介紹了SpringBoot @ModelAttribute使用場(chǎng)景分析,文中通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-08-08Java中的UrlDecoder 和 UrlEncoder_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
HTML 格式編碼的實(shí)用工具類。該類包含了將 String 轉(zhuǎn)換為 application/x-www-form-urlencoded MIME 格式的靜態(tài)方法。下文通過實(shí)例代碼給大家介紹Java中的UrlDecoder 和 UrlEncoder知識(shí),感興趣的的朋友一起看看吧2017-07-07