Spring同包同名的配置類處理方式

同包同名的配置類Spring是如何處理的?

先看一下測試用例

項目結構
項目結構
項目結構
項目結構
運行結果

很遺憾加載了ServiceA,為什么會出現(xiàn)這種情況,我們下面分析一下


為什么會導致這種現(xiàn)象?

掃描的實現(xiàn)類為ClassPathBeanDefinitionScanner,Spring中所有的秒掃方法實現(xiàn)都是委托到這個類來處理的,我們直接看最原始的掃描結果.可以明顯看到這里雖然同包同名但是file的路徑是不同的,所以在掃描處理這個階段是可以區(qū)分的,但是實際上變?yōu)镾cannedGenericBeanDefinition這個對象的時候,它的基類AbstractBeanDefinition的equals方法經(jīng)過自身的重寫,并沒有去考慮實際Resource的不同.也就是存在同包同名的Class這里也只會注冊到容器一個對象(同包同名后面的會替換掉前面的).

可是雖然同包同名,但是我們通過@Profile進行了區(qū)分,這里應該是會把那個不滿足條件的Class跳過才對,也就是應該加載了對的那個Class.這里確實是加載的對的那一個,那么為什么加載了對了那個BeanDefinition我們的注解卻沒有生效呢?這里實際上只解析了指定路徑掃出來的結果,并沒有處理配置類的遞歸解析,我們繼續(xù)往下看看配置類的注解如何解析的.

運行分析

這里看到一旦掃描完成直接判斷掃描到的BeanDefiition是否含有配置類@Configuration注解,如果有的話遞歸解析,但是parse方法并沒有直接使用這個BeanDefiition已經(jīng)解析出的注解而是自己從新加載

運行分析
運行分析
運行分析

可以看到這里加載了錯誤的元信息回去,但是實際上這里解析不會出問題的,因為processConfigurationClass方法會判斷@Conditional注解的條件.

運行分析

到這里都沒有載入錯誤的信息,那到底這些錯誤的注解實在哪里解析的?繼續(xù)往下看,追蹤到所有解析的入口在ConfigurationClassPostProcessor的processConfigBeanDefinitions方法.

先看一下主要的相關邏輯.去除了部分其他邏輯細節(jié)

運行分析

在第一次掃描完之后原來外層還會再判斷一次配置類是否加載,這里可是從BeanDefiition取出來正確的元信息了,那么會加載正確嗎?

運行分析
運行分析

下面就找到了最終加載錯誤的元兇了...

運行分析
運行分析
運行分析

可以看到最后還是通過正確的BeanDefinition跳過驗證,后面通過緩存加載了錯誤的類元信息,導致后面解析類元信息解析錯誤.


3總結

盡量避免同包,每個項目的package都應該有自己獨立的頂層package這樣能避免同包同名導致的錯誤.相同包內如果同名會提示錯誤的,所以同項目同包目錄下不擔心同名問題.


4其他

示例源碼:github源碼地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,253評論 6 342
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,765評論 25 709
  • 【60天月度檢視】郭志斌 第一組郭思彤家長 郭志斌 作者 2017.10.01 22: 00 【基本情況】 姓名:...
    配誌閱讀 390評論 0 0
  • 今天要跟大家講的故事,發(fā)生在2007年,也就是十年前,同樣是這樣一個涼爽的季節(jié),韓旭和敬文他們相識了。他們的第一次...
    劉建業(yè)閱讀 244評論 0 0
  • 感覺有更多優(yōu)秀的訂閱號,有許多的大伽,有些觀點都有些重復,或者是在哪里已經(jīng)看到過得,所以我覺得應該花時間把基礎課學...
    莉香讀書閱讀 202評論 0 0

友情鏈接更多精彩內容