Springbean中BeanPostProcessor怎么用-創(chuàng)新互聯(lián)

這篇文章主要介紹了Spring bean中BeanPostProcessor怎么用,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的下陸網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

前言

之前有提到通過InitializingBean和Disposable等接口可以對(duì)bean的初始化和銷毀做一些自定義操作,那么有一點(diǎn)要注意,那僅僅是在bean被容器實(shí)例化之后的操作,在spring的世界里,要想對(duì)實(shí)例化這個(gè)過程做點(diǎn)什么,作為一個(gè)普通業(yè)務(wù)的開發(fā)人員,顯然不需要去繼承ApplicationContext或者BeanFactory,因?yàn)閟pring container為我們提供了一些接口,讓我們以插件的形式去擴(kuò)展BeanFactory對(duì)bean的初始化操作,其中就有我們今天的主角——BeanPostProcessor(以下簡(jiǎn)稱bpp)接口。

源碼,先睹為快

Spring bean中BeanPostProcessor怎么用

這個(gè)用法很簡(jiǎn)單,它只有兩個(gè)方法,我們實(shí)現(xiàn)自己的BeanPostProcessor,Spring能自動(dòng)注冊(cè)到容器中。

其中before方法是在bean實(shí)例化之后,屬性設(shè)置之后但在初始化方法之前執(zhí)行;after方法是在各種初始化方法之后執(zhí)行。

說到這里可能有人會(huì)想,這跟生命周期中的其它初始化接口有啥區(qū)別?其它的初始化方法也可以修改bean啊,這個(gè)問題問得好,那么我們來說下這個(gè)接口與InitializingBean Disposable接口以及自定義的init destroy方法的本質(zhì)區(qū)別

  • bpp的兩個(gè)方法是有返回值Object的,這恰恰是問題的關(guān)鍵,這個(gè)bean就是我們要修改的bean,這樣一來,我們就可以修改bean實(shí)例本身,或替換,或wrap成一個(gè)proxy bean(Spring中的aop機(jī)制多是這么干),而其它的初始化接口的返回為void,因此它們理論上只能修改bean的狀態(tài),能做的東西相當(dāng)受限制。

  • bpp是以擴(kuò)展插件的形式被Container執(zhí)行,不需要bean本身去做什么(bean本身不用實(shí)現(xiàn)這個(gè)接口),所以這個(gè)插件跟bean在代碼上不耦合

  • 在執(zhí)行方式上也完全不同,bpp是作為Spring container的一個(gè)擴(kuò)展,在容器初始化bean的過程過,對(duì)每個(gè)bean都會(huì)執(zhí)行一次,而初始化接口,由于是特定的bean實(shí)現(xiàn)的,所以與其它的bean無(wú)關(guān),只對(duì)初始該類型的bean執(zhí)行。簡(jiǎn)而言之就是,雖然都是由容器執(zhí)行對(duì)bean的操作,bpp是擴(kuò)展的容器本身行為,而初始化接口是擴(kuò)展bean的行為后被容器執(zhí)行的。

在這里有兩種特殊的bpp不得不說,假設(shè)你需要自定義一個(gè)類似于@Autowire或者@Inject的注入功能的注解的時(shí)候(你可能會(huì)用到InjectionMetadata),普通的bpp可能就滿足不了你的需要了,你可能用到兩個(gè)特殊的bpp。

MergedBeanDefinitionPostProcessor(以下簡(jiǎn)稱mbdpp)

InstantiationAwareBeanPostProcessor(以下簡(jiǎn)稱iabpp)

他們都是繼承自bpp,但在spring bean 創(chuàng)建的過程中切入點(diǎn)不同于普通的bpp。

InstantiationAwareBeanPostProcessor接口

Spring bean中BeanPostProcessor怎么用

 看注釋

Spring bean中BeanPostProcessor怎么用

postProcessBeforeInstantiation方法

查閱AbstractAutowireCapableBeanFactory的createBean方法(這個(gè)方法是Spring容器創(chuàng)建bean的核心方法),可以看到,postProcessBeforeInstantiation是在bean實(shí)例化之前,postProcessAfterInstantiation是在實(shí)例化之后屬性設(shè)置以及autowire注入之前,它一般是spring框架內(nèi)部使用,但在這里大有可為,用postProcessBeforeInstantiation可以生成代理對(duì)象( 一般作法是讓postProcessorBeforeInstantiation方法返回不為null,這樣就會(huì)中斷后續(xù)創(chuàng)建bean實(shí)例的過程,會(huì)以這個(gè)方法返回的對(duì)象作為bean實(shí)例),看源碼:

Spring bean中BeanPostProcessor怎么用

postProcessPropertyValues方法

用postProcessPropertyValues 可以完成對(duì)屬性的各種操作,注解中元數(shù)據(jù)的解析等,Spring的@Autowire注入,JSR330的@Inject以及JSR250的@Resource等注入操作都是通過這個(gè)方法完成。

這接口的用處在spring底層較多,有興趣的同學(xué)可以翻閱源碼,以下是兩個(gè)比較典型的實(shí)現(xiàn)。

AutowiredAnnotationBeanPostProcessor
AbstractAutoProxyCreator

MergedBeanDefinitionPostProcessor接口

Spring bean中BeanPostProcessor怎么用

這個(gè)接口傳入了一個(gè)RootBeanDefinition,這里允許我們修改bean的定義,@AutuwiredAnnotationBeanPostProcessor通過實(shí)現(xiàn)這個(gè)方法檢查并注冊(cè)需要注入的成員。

BeanFactoryPostProcessor(bfpp)

除了BeanPostProcessor還有一種想必大家都知道,那就是BeanFactoryPostProcessor

bfpp是作為beanFactory的一個(gè)很重要擴(kuò)展插件,可以用來自定義BeanDefination的。它與bpp主要區(qū)別在于:

  • bpp是處理的bean實(shí)例,bfpp是處理bean的定義

  • bfpp能讀取和修改bean的定義(BeanDefination),比如說在配置中屬性值用到的占位符${}就是PropertyPlaceholderConfigurer通過實(shí)現(xiàn)bfpp來實(shí)現(xiàn)的

  • bpp處理的則是新鮮出爐并且設(shè)置好屬性的bean的實(shí)例(上邊提到iabpp和mdbpp的兩種特殊的bpp除外)

好了,說了這么多,來看下Spring創(chuàng)建bean的大致流程圖,這里只標(biāo)出了比較關(guān)鍵的節(jié)點(diǎn)

 Spring bean中BeanPostProcessor怎么用

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Spring bean中BeanPostProcessor怎么用”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

當(dāng)前名稱:Springbean中BeanPostProcessor怎么用-創(chuàng)新互聯(lián)
文章路徑:http://muchs.cn/article42/csjhec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、服務(wù)器托管、響應(yīng)式網(wǎng)站、用戶體驗(yàn)、動(dòng)態(tài)網(wǎng)站、網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)