前言
前面的篇幅裡有提到通過InitializingBean和Disposable等接口可以對bean的初始化和銷毀做一些自定義操作,那麼有一點要注意,那僅僅是在bean被容器實例化之後的操作,在spring的世界裡,要想對實例化這個過程做點什麼,作為一個普通業務的開發人員,顯然不需要去繼承ApplicationContext或者BeanFactory,因為spring container為我們提供了一些接口,讓我們以插件的形式去擴展BeanFactory對bean的初始化操作,其中就有我們今天的主角――BeanPostProcessor(以下簡稱bpp)接口。
源碼,先睹為快
這個用法很簡單,它只有兩個方法,我們實現自己的BeanPostProcessor,Spring能自動註冊到容器中。
其中before方法是在bean實例化之後,屬性設置之後但在初始化方法之前執行;after方法是在各種初始化方法之後執行。
說到這裡可能有人會想,這跟生命週期中的其它初始化接口有啥區別?其它的初始化方法也可以修改bean啊,這個問題問得好,那麼我們來說下這個接口與InitializingBean Disposable接口以及自定義的init destroy方法的本質區別
在這裡有兩種特殊的bpp不得不說,假設你需要自定義一個類似於@Autowire或者@Inject的注入功能的註解的時候(你可能會用到InjectionMetadata),普通的bpp可能就滿足不了你的需要了,你可能用到兩個特殊的bpp。
MergedBeanDefinitionPostProcessor(以下簡稱mbdpp)
InstantiationAwareBeanPostProcessor(以下簡稱iabpp)
他們都是繼承自bpp,但在spring bean 創建的過程中切入點不同於普通的bpp。
InstantiationAwareBeanPostProcessor接口
看註釋
postProcessBeforeInstantiation方法
查閱AbstractAutowireCapableBeanFactory的createBean方法(這個方法是Spring容器創建bean的核心方法),可以看到,postProcessBeforeInstantiation是在bean實例化之前,postProcessAfterInstantiation是在實例化之後屬性設置以及autowire注入之前,它一般是spring框架內部使用,但在這里大有可為,用postProcessBeforeInstantiation可以生成代理對象( 一般作法是讓postProcessorBeforeInstantiation方法返回不為null,這樣就會中斷後續創建bean實例的過程,會以這個方法返回的對像作為bean實例),看源碼:
postProcessPropertyValues方法
用postProcessPropertyValues 可以完成對屬性的各種操作,註解中元數據的解析等,Spring的@Autowire注入,JSR330的@Inject以及JSR250的@Resource等注入操作都是通過這個方法完成。
這接口的用處在spring底層較多,有興趣的同學可以翻閱源碼,以下是兩個比較典型的實現。
AutowiredAnnotationBeanPostProcessor
AbstractAutoProxyCreator
MergedBeanDefinitionPostProcessor接口
這個接口傳入了一個RootBeanDefinition,這裡允許我們修改bean的定義,@AutuwiredAnnotationBeanPostProcessor通過實現這個方法檢查並註冊需要注入的成員。
BeanFactoryPostProcessor(bfpp)
除了BeanPostProcessor還有一種想必大家都知道,那就是BeanFactoryPostProcessor
bfpp是作為beanFactory的一個很重要擴展插件,可以用來自定義BeanDefination的。它與bpp主要區別在於:
好了,說了這麼多,來看下Spring創建bean的大致流程圖,這裡只標出了比較關鍵的節點
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。