生命太短暫,不要去做一些根本沒有人想要的東西。本文已被 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模式
- 自Spring 5.2.0版本后它加了個
@Bean:標注在方法上,表示方法生成一個由Spring容器管理的BeanConfigurationClassPostProcessor:用於引導處理@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:有小伙伴私信我說有沒有入門級別的?答案是沒有的。主要是覺得入門級文章網上太多了,趨同性很強,所以我這一般會篇進階,有點工作經驗/基礎再看效果更佳
