AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

Springboot擴展點之BeanDefinitionRegistryPostProcessor,你學會了嗎?

來源: 責編: 時間:2023-11-28 09:36:33 249觀看
導讀前言通過這篇文章來大家分享一下,另外一個Springboot的擴展點BeanDefinitionRegistryPostProcessor,一般稱這類擴展點為容器級后置處理器,另外一類是Bean級的后置處理器;容器級的后置處理器會在Spring容器初始化后、刷新

前言

通過這篇文章來大家分享一下,另外一個Springboot的擴展點BeanDefinitionRegistryPostProcessor,一般稱這類擴展點為容器級后置處理器,另外一類是Bean級的后置處理器;容器級的后置處理器會在Spring容器初始化后、刷新前這個時間執行一次,Bean級的后置處理器,則是在每一個Bean實例化前后都會執行。RYG28資訊網——每日最新資訊28at.com

圖片圖片RYG28資訊網——每日最新資訊28at.com

功能特性

  1. postProcessBeanDefinitionRegistry()方法 可以通過BeanDefinitionRegistry對BeanDefintion進行增刪改查;
  2. 繼承了BeanFactoryPostProcessor,BeanFactoryPostProcessor是容器級別的擴展接口,org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory方法在容器實例化后、刷新容器前被執行,即在容器刷新前還可以對BeanDefintion再作一些操作;
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {   void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;}
@FunctionalInterfacepublic interface BeanFactoryPostProcessor {   void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;}

總結起來就是,在所有的BeanDefinition加載完成之后,Bean真正被實例化之前,可以通過實現BeanDefinitionRegistryPostProcessor接口,對BeanDefinition再做一些定制化的操作,比如修改某個bean的BeanDefinition的屬性、手動注冊一些復雜的Bean。RYG28資訊網——每日最新資訊28at.com

對于Spring原理不太熟悉的小伙伴心里看到這可能有點暈了,BeanDefinition是什么?BeanDefinitionRegistry又是什么?ConfigurableListableBeanFactory又又是什么?別著急,這里拐個彎簡單的解釋一下,方便下面的內容理解起來更順暢。RYG28資訊網——每日最新資訊28at.com

BeanDefinition

大家都知道,Spring的核心之一是IOC(控制反轉),Spring之所以可以實現bean控制權的反轉,是因為Spring的容器功能,在bean納入Spring容器管理前,所有bean會被抽象封裝成一個BeanDefinition實例,然后會在不同的時機根據BeanDefinition實例信息對bean進行實例化。RYG28資訊網——每日最新資訊28at.com

簡單說,Dog.java描述狗這一類動物的屬性和行為,BeanDefinition描述Dog.java這個類。RYG28資訊網——每日最新資訊28at.com

BeanDefinitionRegistry

BeanDefinitionRegistry從字面意思看是bean的定義信息的注冊登記,其實這個類的功能和字面意思一樣,就是對BeanDefinition進行管理(增刪改查);RYG28資訊網——每日最新資訊28at.com

public interface BeanDefinitionRegistry extends AliasRegistry {    //注冊beanDefinition   void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)         throws BeanDefinitionStoreException;    //移除指定的beanDefinition   void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;    //根據beanName查詢beanDefinition   BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;    //判斷某個beanDefinition是否已經注冊   boolean containsBeanDefinition(String beanName);    //獲取所有已注冊的beanDefinition   String[] getBeanDefinitionNames();    //獲取所有已注冊的beanDefinition的數量   int getBeanDefinitionCount();    //判斷某個beanDefinition是否已經被使用   boolean isBeanNameInUse(String beanName);}

ConfigurableListableBeanFactory

上面提到了Spring的容器,Spring的核心之一是IOC,那么Spring的容器設計就是核心中的核心了。Spring的容器有多種形態,最基礎的形態就是BeanFactory,ConfigurableListableBeanFactory間接繼承了BeanFactory,因此ConfigurableListableBeanFactory實現類除了有Spring基礎版本容器的功能外,還有一些高級的功能,Springboot默認的實際實現是DefaultListableBeanFactory,有興趣的小伙伴可以以此為入口深入探究一番,這里不展開細說了。RYG28資訊網——每日最新資訊28at.com

圖片圖片RYG28資訊網——每日最新資訊28at.com

自定義實現

MyBeanDefinitionRegistryPostProcessor

下面通過一個具體類MyBeanDefinitionRegistryPostProcessor實現BeanDefinitionRegistryPostProcessor接口,來探究BeanDefinitionRegistryPostProcessor實現類的初始化和執行過程。RYG28資訊網——每日最新資訊28at.com

  1. 在postProcessBeanDefinitionRegistry()方法被調用的時候手工在Spring中注冊了Dog類的BeanDefinition信息;
  2. 在postProcessBeanFactory()方法被調用的時候,從Spring容器中取出Dog類的BeanDefinition信息和Dog類的實例;
@Datapublic class Dog {    private String name;    private String color;}
@Componentpublic class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {    @Override    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {        //手工定義一個beanDefinition實例        RootBeanDefinition beanDefinition = new RootBeanDefinition();        //給beanDefinition填充屬性        beanDefinition.setBeanClass(Dog.class);        MutablePropertyValues propertyValues = new MutablePropertyValues();        PropertyValue propertyValue1 = new PropertyValue("name", "旺財");        PropertyValue propertyValue2 = new PropertyValue("color", "黑色");        propertyValues.addPropertyValue(propertyValue1);        propertyValues.addPropertyValue(propertyValue2);        beanDefinition.setPropertyValues(propertyValues);        //注冊手工定義的beanDefinition        registry.registerBeanDefinition("dog", beanDefinition);    }    @Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {        System.out.println("-----------start------------");        //根據類名取出手工注冊的beanDefinition        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("dog");        System.out.println(beanDefinition.getBeanClassName());        //根據類從容器中取出手工注冊的beanDefinition所描述的實例bean        Dog dog = beanFactory.getBean(Dog.class);        System.out.println(dog.getName());        System.out.println(dog.getColor());        System.out.println("-----------end------------");    }}

單元測試RYG28資訊網——每日最新資訊28at.com

@Testpublic void test(){    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.fanfu");    Dog dog = ((Dog) context.getBean("dog"));    System.out.println(dog.getName());    System.out.println(dog.getColor());}

UML類圖

通過BeanDefinitionRegistryPostProcessorUML類圖可以看出BeanDefinitionRegistryPostProcessor繼承了BeanFactoryPostProcessor,postProcessBeanDefinitionRegistry()方法屬于BeanDefinitionRegistryPostProcessor,postProcessBeanFactory()屬于BeanFactoryPostProcessor,所有實現了BeanDefinitionRegistryPostProcessor接口的實現類都需要實現這個方法,而作為Springboot的擴展點之一,其擴展的邏輯也在這兩個方法中;RYG28資訊網——每日最新資訊28at.com

圖片圖片RYG28資訊網——每日最新資訊28at.com

初始化和執行時機

通過自定義的MyBeanDefinitionRegistryPostProcessor類,實現BeanDefinitionRegistryPostProcessor接口,從項目啟動開始,其執行過程如下:RYG28資訊網——每日最新資訊28at.com

  1. 執行項目的主類,SpringApplication#run被調用;
  2. 進入boot.SpringApplication#run方法后,剛開始是一些Spring容器初始化的配置操作,直到執行到SpringApplication#refreshContext,開始容器刷新,進入了關鍵階段;
  3. 在SpringApplication#refreshContext,實際的刷新邏輯是在AbstractApplicationContext#refresh方法中;
  4. AbstractApplicationContext#refresh方法中,調用AbstractApplicationContext#invokeBeanFactoryPostProcessors開始初始化和執行實現BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry()和postProcessBeanFactory();
  5. 進入AbstractApplicationContext#invokeBeanFactoryPostProcessors方法,發現又調用了PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors();
  6. 在PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()方法中,并不是直接就初始化和執行postProcessBeanDefinitionRegistry()和postProcessBeanFactory(),而是又進行了一系列的判斷,其判斷順序是:1、通過AbstractApplicationContext#addBeanFactoryPostProcessor提前注冊的BeanDefinitionRegistryPostProcessor實現類;2、實現了PriorityOrdered接口;3、是否實現了Ordered;4、剩下的其他BeanDefinitionRegistryPostProcessor實現類;自定義的MyBeanDefinitionRegistryPostProcessor就屬于第4類,所以是所有實現里較晚才被執行的,如果想要提前被執行,可以考慮前面三種方式;
  7. 在PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()方法中執行完MyBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法后,緊接著就開始執行MyBeanDefinitionRegistryPostProcessor#postProcessBeanFactory方法了;從整個調用過程看postProcessBeanDefinitionRegistry()是早于postProcessBeanFactory()方法執行;

下面是我根據整個調用過程畫的一個時序圖,過程確實比較復雜,但是邏輯比較清晰,因此并不難理解,想要真的搞清楚整個過程,最好的方法就是照著這個圖,親自執行一遍,通過debug觀察每一個關鍵節點的執行過程。RYG28資訊網——每日最新資訊28at.com

圖片圖片RYG28資訊網——每日最新資訊28at.com

內部實現類

spring-boot-starter-web中內置的實現類有CachingMetadataReaderFactoryPostProcessor、ConfigurationClassPostProcessor、ConfigurationWarningsPostProcessor、EmbeddedDataSourceBeanFactoryPostProcessor、ImportsCleanupPostProcessor、TestRestTemplateRegistrar、WebTestClientRegistrar、WsdlDefinitionBeanFactoryPostProcessor,觀察一下每個實現類會發現:都比較類似,這些內置實現類都是Springboot中的內部類,通過這些BeanDefinitionRegistryPostProcessor內部實現類向Spring容器中注冊了一些特殊的BeanDefinition,如果展開詳細再說一說這些Bean,怕是一天一夜也說不完,有興趣的小伙伴可以深入了解一下,這里就不再展開了。RYG28資訊網——每日最新資訊28at.com

總結

通過梳理整個過程,其實最關鍵的就是一句話:在Spring容器初始后、未刷新前,即Bean已被掃描注冊為BeanDefinition后,未正式實例化前,可以通過實現BeanDefinitionRegistryPostProcessor做一些額外的操作。RYG28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-34657-0.htmlSpringboot擴展點之BeanDefinitionRegistryPostProcessor,你學會了嗎?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 一個注解搞定多數據源切換,你學會了嗎?

下一篇: 100行代碼實現審計日志中間件

標簽:
  • 熱門焦點
  • K60至尊版狂暴引擎2.0加持:超177萬跑分斬獲性能第一

    Redmi的后性能時代戰略發布會今天下午如期舉辦,在本次發布會上,Redmi公布了多項關于和聯發科的深度合作,以及新機K60 Ultra在軟件和硬件方面的特性,例如:“K60 至尊版,雙芯旗艦
  • 2023 年的 Node.js 生態系統

    隨著技術的不斷演進和創新,Node.js 在 2023 年達到了一個新的高度。Node.js 擁有一個龐大的生態系統,可以幫助開發人員更快地實現復雜的應用。本文就來看看 Node.js 最新的生
  • Temu起訴SHEIN,跨境電商戰事升級

    來源 | 伯虎財經(bohuFN)作者 | 陳平安日前據外媒報道,拼多多旗下跨境電商平臺Temu正對競爭對手SHEIN提起新訴訟,訴狀稱Shein“利用市場支配力量強迫服裝廠商與之簽訂獨家
  • 大廠卷向扁平化

    來源:新熵作者丨南枝 編輯丨月見大廠職級不香了。俗話說,兵無常勢,水無常形,互聯網企業調整職級體系并不稀奇。7月13日,淘寶天貓集團啟動了近年來最大的人力制度改革,目前已形成一
  • iQOO 11S新品發布會

    iQOO將在7月4日19:00舉行新品發布會,推出杭州亞運會電競賽事官方用機iQOO 11S。
  • iQOO 11S或7月上市:搭載“雞血版”驍龍8Gen2 史上最強5G Soc

    去年底,iQOO推出了“電競旗艦”iQOO 11系列,作為一款性能強機,iQOO 11不僅全球首發2K 144Hz E6全感屏,搭載了第二代驍龍8平臺及144Hz電競屏,同時在快充
  • Android 14發布:首批適配機型公布

    5月11日消息,谷歌在今天凌晨舉行了I/O大會,本次發布會谷歌帶來了自家的AI語言模型PaLM 2、谷歌Pixel Fold折疊屏、谷歌Pixel 7a手機,同時發布了Androi
  • 英特爾Xe-HP項目終止,將專注Xe-HPC/HPG系列顯卡

    據10 月 31 日消息報道,英特爾高級副總裁兼加速計算系統和圖形事業部總經理 表示,Xe-HP“ Arctic Sound” 系列服務器 GPU 已經應用于 oneAPI devcloud 云服
  • 2022爆款:ROG魔霸6 冰川散熱系統持續護航

    喜逢開學季,各大商家開始推出自己的新產品,進行打折促銷活動。對于忠實的端游愛好者來說,能夠擁有一款夢寐以求的筆記本電腦是一件十分開心的事。但是現在的
Top