Bean實(shí)例化之前修改BeanDefinition示例詳解
BeanFactory
BeanFactory是Spring中容器功能的基礎(chǔ),用于存放所有已經(jīng)加載的bean,為了保證程序上的高可擴(kuò)展性,Spring針對(duì)BeanFactory做了大量的擴(kuò)展。BeanFactoryPostProcessor是BeanFactory的后置處理器;比如在postProcessBeanFactory方法中,可以獲取BeanDefinition的相關(guān)對(duì)象,并且修改該對(duì)象的屬性。
@FunctionalInterface public interface BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException; }
通過(guò)BeanDefinition對(duì)象實(shí)例化Bean對(duì)象
Spring IOC在實(shí)例化Bean對(duì)象之前,需要先讀取Bean的相關(guān)屬性,保存到BeanDefinition
對(duì)象中,然后通過(guò)BeanDefinition對(duì)象,實(shí)例化Bean對(duì)象。如果我們需要修改BeanDefinition對(duì)象中的屬性,就可以實(shí)現(xiàn)BeanFactoryPostProcessor接口,重寫postProcessBeanFactory方法進(jìn)行自定義,是不是很方便呢。
@Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory; BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class); beanDefinitionBuilder.addPropertyValue("id", 123456); beanDefinitionBuilder.addPropertyValue("label", "技術(shù)那些事兒"); defaultListableBeanFactory.registerBeanDefinition("user", beanDefinitionBuilder.getBeanDefinition()); } }
BeanFactoryPostProcessor使用目的:在BeanFactory標(biāo)準(zhǔn)初始化之后調(diào)用,用來(lái)定制和修改BeanFactory的內(nèi)容;
BeanFactoryPostProcessor工作時(shí)機(jī):所有的bean定義已經(jīng)保存加載到beanFactory中,但bean的實(shí)例還沒(méi)創(chuàng)建;
BeanFactoryPostProcessor和BeanPostProcessor類似,可以對(duì)beanDefinition進(jìn)行處理,也就是說(shuō)SpringIOC容器允許BeanFactoryPostProcessor在容器實(shí)際實(shí)例化任何bean之前讀取beanDefinition,并有可能修改它。并且我們還可以配置自定義的BeanFactoryPostProcessor,如果想改變bean,那么使用beanPostProcessor。
并可以通過(guò)order屬性來(lái)控制BeanFactoryPostProcessor的執(zhí)行次序;因?yàn)橹挥袑?shí)現(xiàn)了Ordered接口時(shí),才可以設(shè)置這個(gè)屬性,所以在實(shí)現(xiàn)BeanFactoryPostProcessor的時(shí)候,就應(yīng)該考慮實(shí)現(xiàn)Ordered接口。
BeanFactoryPostProcessor的作用域是容器級(jí)的,只和你使用的容器有關(guān),如果在一個(gè)容器中定義了一個(gè)BeanFactoryPostProcessor,它僅僅對(duì)此容器中的beanDefinition進(jìn)行后處理。BeanFactoryPostProcessor不會(huì)對(duì)定義在另一個(gè)容器中的bean進(jìn)行后處理,即便這兩個(gè)容器都在同一個(gè)層次上。
BeanFactoryPostProcessor還有一個(gè)子接口BeanDefinitionRegistryPostProcessor,其內(nèi)部添加了一個(gè)方法postProcessBeanDefinitionRegistry:
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
ConfigurationClassPostProcessor這個(gè)類非常重要,其實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor接口與PriorityOrdered接口:
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { int registryId = System.identityHashCode(registry); if (this.registriesPostProcessed.contains(registryId)) { throw new IllegalStateException( "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry); } if (this.factoriesPostProcessed.contains(registryId)) { throw new IllegalStateException( "postProcessBeanFactory already called on this post-processor against " + registry); } this.registriesPostProcessed.add(registryId); /** * @author lcy * 處理配置beanDefinition */ processConfigBeanDefinitions(registry); }
就是在這個(gè)方法里將配置類指定的類解析為BeanDefinition對(duì)象,并放入BeanFactory的beanDefinitionMap中。還有一點(diǎn)需要說(shuō)明,這個(gè)類是在執(zhí)行AnnotationConfigApplicationContext的無(wú)參構(gòu)造方法時(shí)被解析為beanDefinition并放入map中的。在AnnotationConfigApplicationContext的refresh()內(nèi)部的 invokeBeanFactoryPostProcessors(beanFactory)方法完成了對(duì) BeanFactoryPostProcessor對(duì)象與BeanDefinitionRegistryPostProcessor對(duì)象相關(guān)方法的執(zhí)行。
以上就是Bean實(shí)例化之前修改BeanDefinition示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Bean實(shí)例化修改BeanDefinition的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Spring啟動(dòng)過(guò)程中實(shí)例化部分代碼的分析之Bean的推斷構(gòu)造方法
- IOC?容器啟動(dòng)和Bean實(shí)例化兩個(gè)階段詳解
- Spring中Bean的三種實(shí)例化方式詳解
- 詳解Spring?Bean的配置方式與實(shí)例化
- Spring實(shí)例化bean的四種方式詳解
- SpringBoot借助spring.factories文件跨模塊實(shí)例化Bean
- Spring Bean生命周期之Bean的實(shí)例化詳解
- 在spring中實(shí)例化bean無(wú)效的問(wèn)題
- 基于springboot bean的實(shí)例化過(guò)程和屬性注入過(guò)程
- Spring之詳解bean的實(shí)例化
相關(guān)文章
SpringBoot Mybatis如何配置多數(shù)據(jù)源并分包
這篇文章主要介紹了SpringBoot Mybatis如何配置多數(shù)據(jù)源并分包,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05JAVA實(shí)現(xiàn)JSON后端向前端傳遞數(shù)據(jù)
本篇文章主要介紹了JAVA實(shí)現(xiàn)JSON后端向前端傳遞數(shù)據(jù),這里整理了詳細(xì)的代碼,具有一定的參考價(jià)值,有需要的小伙伴可以參考下。2017-03-03Spring自動(dòng)配置之condition條件判斷上篇
這篇文章主要為大家介紹了SpringBoot condition條件判斷功能的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08SpringBoot實(shí)現(xiàn)阿里云快遞物流查詢的示例代碼
本文將基于springboot實(shí)現(xiàn)快遞物流查詢,物流信息的獲取通過(guò)阿里云第三方實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2021-10-10基于java實(shí)現(xiàn)斗地主代碼實(shí)例解析
這篇文章主要介紹了基于java實(shí)現(xiàn)斗地主代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07