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

YourBatman發表於2020-07-14

生命太短暫,不要去做一些根本沒有人想要的東西。本文已被 https://www.yourbatman.cn 收錄,裡面一併有Spring技術棧、MyBatis、JVM、中介軟體等小而美的專欄供以免費學習。關注公眾號【BAT的烏托邦】逐個擊破,深入掌握,拒絕淺嘗輒止。

前言

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

相關文章