Spring配置類深度剖析-總結篇(手繪流程圖,可白嫖)

當大潮退去,才知道誰在裸泳。
作者:A哥(YourBatman)
公衆號:BAT的烏托邦(ID:BAT-utopia)
文末是否有彩蛋:有

前言

各位小夥伴大家好,我是A哥。最近寫了好幾篇關於Spring @Configuration的文章,收錄在Spring配置類專欄裏,這是本公衆號的第一個專欄(雖然CSDN裏已有幾百篇)。雖然寫的過程很艱難,但從評價反饋來看都是正向的,聊以安慰唄,比如這個小夥的“三宗最”讓我聽了很開心啊😄:
在這裏插入圖片描述
雖然每篇文章的閱讀量堪憂,畢竟從第一篇文章我就對我自己的公衆號定位了嘛:不求大量流行,只求小衆共鳴。因爲我知道願意堅持看下去系列文章(強依賴於上下文)的小夥伴還是比較少的,但我相信一旦堅持下來我們的共同話題就多了,“臭味相投”嘛,是這樣的吧~

在這之前,CSDN裏寫過幾百篇關於Spring的文章,但是總感覺體系性不夠,東打一炮,西放一槍難免會有失連貫性。我一直認爲大多時候技術的相關性、上下文上很必要的,僅靠一篇文章想把一個成型的知識點講清楚幾乎沒可能,所以那種容易成爲快餐,過眼即忘。這不這次我選擇在公衆號裏做些成系列的專題,在CSDN的基礎上,抽取精華,去其糟粕,以自身能力盡量的做好每一個專欄,普惠於有需要的小夥伴。過程很枯燥和很乏味,願意看下去的人也不會很多,能堅持下來或許會被自己感動😄。

作爲第一個專欄的總結篇,一般的都是少文字多流程圖,旨在起到一個總覽的作用,也爲方便快速應付面試~
在這裏插入圖片描述


版本約定

本文內容若沒做特殊說明,均基於以下版本:

  • JDK:1.8
  • Spring Framework:5.2.2.RELEASE

正文

相關類

  • @Configuration:標註在類上,表示該類是個Full模式的配置類
    • 自Spring 5.2.0版本後它加了個proxyBeanMethods屬性來顯示控制Full模式還是Lite模式,默認是true表示Full模式
  • @Bean:標註在方法上,表示方法生成一個由Spring容器管理的Bean
  • ConfigurationClassPostProcessor:用於引導處理@Configuration配置類的後置處理器。注意:它只是引導處理,並不是實際處理
  • ConfigurationClassUtils:內部工具類。用於判斷組件是否是配置類,又或是Full模式/Lite模式,然後在bd元數據裏打上標記
    • 它還會處理一件小事:獲取@Configuration配置類上標註的@Order排序值並放進bd裏
  • BeanMethod:內部使用的類。用於封裝標註有@Bean註解的方法
  • ConfigurationClass:內部使用的類。每一個@Configuration配置類都會被封裝爲它,內部會包含多個@Bean方法(BeanMethod)
  • ConfigurationClassParser:解析@Configuration配置類,最終以ConfigurationClass對象的形式展示,並且填充它:因爲一個配置類可以@Import導入另外一個(或者N多個)其它配置類,所以需要填充
  • ConfigurationClassBeanDefinitionReader:內部使用的類。讀取給定的已經解析好的Set<ConfigurationClass>集合,把裏面的bd信息註冊到BeanDefinitionRegistry裏去(這裏決定了bd的有序和無序相關問題)
  • ConfigurationClassEnhancer:內部使用的類。配置類增強器,用於對@Configuration類(Full模式)使用CGLIB增強,生成一個代理子類字節碼Class對象
  • EnhancedConfiguration:被增強器增強過的配置類,都會自動的讓實現此接口(實際是個BeanFactoryAware)接口
  • SpringNamingPolicy:使用CGLIB生成字節碼類名名稱生成策略 -> 名稱中會有BySpringCGLIB字樣
  • BeanFactoryAwareMethodInterceptor:CGLIB代理對象攔截器。作用:攔截代理類的setBeanFactory()方法,給對應屬性賦值
  • BeanMethodInterceptor:CGLIB代理對象攔截器。作用:攔截所有@Bean方法的執行,以支持可以通過直接調用@Bean方法來管理依賴關係(當然也支持FactoryBean模式)

配置類解析流程圖

配置類的解析均是交由ConfigurationClassPostProcessor來引導。在Spring Framework裏(非Spring Boot)裏,它是BeanDefinitionRegistryPostProcessor處理器的唯一實現類,用於引導處理@Configuration配置類。解析入口是postProcessBeanDefinitionRegistry()方法,實際處理委託給了processConfigBeanDefinitions()方法。
在這裏插入圖片描述


配置類增強流程圖

如果一個配置類是Full模式,那麼它就需要被CGLIB字節碼提升。增強動作委託給enhanceConfigurationClasses(beanFactory)去完成。
在這裏插入圖片描述

以上是引導/調度的流程圖,下面對字節碼增強、實際攔截實現流程進行細分描述。


生成增強子類字節碼流程圖

針對於Full模式配置類的字節碼生成,委託給ConfigurationClassEnhancer增強器去完成,最終得到一個CGLIB提升過的子類Class字節碼對象
在這裏插入圖片描述
字節碼實際是由Enhancer生成,就不用再深入了,那屬於CGLIB(甚至ASM)的範疇,很容易頭暈,也並無必要。


攔截器執行流程圖

攔截器是完成增強實際邏輯的核心部件,因此它的執行流程需要引起重視。一共有兩個“有用”的攔截器,分別畫出。


BeanFactoryAwareMethodInterceptor攔截流程圖

攔截setBeanFactory()方法的執行
在這裏插入圖片描述


BeanMethodInterceptor攔截流程圖

攔截@Bean方法的執行
在這裏插入圖片描述


總結

本文作爲公衆號首個專欄Spring配置類的總結篇,主要是對核心處理流程畫圖闡述,適合需要快速理解的白嫖黨,畢竟面試最喜歡問的就是讓你說說執行流程之類的,因此實用性還是蠻高的,以後的專欄均會仿造此套路來玩。

關於Spring配置類這個專欄到這就全部結束了,在此也多謝各位在這期間給我的反饋,讓我確定以及肯定了這麼堅持下去是有意義的,是被支持的,是能夠幫助到同仁們的。我公衆號定位爲專欄式學習,拒絕淺嘗遏止,誠邀你的關注,一起進步。

Tips:有小夥伴私信我說有沒有入門級別的?答案是沒有的。主要是覺得入門級文章網上太多了,趨同性很強,所以我這一般會篇進階,有點工作經驗/基礎再看效果更佳


關於A哥

  • 專欄式學習咱們小衆聊,拒絕淺嘗輒止。知識星球誠邀您掃碼入駐(提示:請務必先關注公衆號,回覆 知識星球 領取優惠券後再輕裝入駐)
  • 私人微信,掃碼加A哥好友(備註:“公衆號”),邀你進入 Java高工、架構師 系列純技術羣(或關注公衆號,回覆 加羣 亦可直接加入)
  • 文章在公衆號首發,其它平臺慢1-2天。也可關注A哥的個人博客:https://www.yourbatman.cn

    碼字非常不易,不可以白嫖,點個在看就表示你支持A哥的原創嘍~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章