春季 - 為什麼要逐名 - 擬議中的標準
Spring 依賴注入:為何無法自動按名稱匹配?
Spring 的依賴注入機制主要基於類型,而非名稱。當遇到多個相同類型的 Bean 時(例如 TenantDataSource),它不會自動回退到按參數名稱匹配。這是因為 Spring 無法始終保證方法中的參數名稱與 Bean 名稱匹配。
Java 默認情況下不會在編譯後的字節碼中保留參數名稱。如果沒有特殊配置,參數名稱(例如 tenantADataSource 和 tenantBDataSource)會在編譯期間被清除,並替換為通用的名稱,如 arg0 和 arg1。 因此,Spring 無法得知 tenantADataSource 指的是名為 "tenantA-dataSource" 的 Bean。
解決參數名稱保留問題
可以使用 -parameters
編譯器標誌來保留字節碼中的參數名稱:
<code>javac -parameters MyClass.java</code>
即使使用了此標誌,Spring 仍然不會按參數名稱匹配,除非明確配置。
Spring 避免做出假設以防止意外行為。例如,如果參數名稱意外交換或命名錯誤,或者開發人員期望不同的映射,會發生什麼? 如果沒有明確的指導(例如 @Qualifier
),Spring 無法確定開發人員的意圖,而選擇拋出錯誤,而不是可能注入錯誤的 Bean。
Spring 遵循“顯式優於隱式”的原則。依賴注入應該具有可預測性,並且不依賴於參數名稱到 Bean 名稱匹配之類的假設。 Spring 的運作方式在不同的環境和框架中保持一致。某些語言或框架(如 Kotlin)默認保留參數名稱,而其他語言則不保留,因此 Spring 避免依賴參數名稱來實現關鍵功能。
何時名稱匹配可以自動工作?
雖然 Spring 默認情況下不按參數名稱匹配,但在某些情況下可以按參數名稱匹配,但這取決於您的設置:
Spring 4.3 參數名稱發現
如果使用 -parameters
標誌編譯代碼,當存在歧義時,Spring 可以從參數名稱推斷 Bean 名稱。
示例:
<code>@Autowired public TenantService(TenantDataSource tenantADataSource, TenantDataSource tenantBDataSource) { this.tenantADataSource = tenantADataSource; this.tenantBDataSource = tenantBDataSource; }</code>
如果使用了 -parameters
標誌並且參數名稱(tenantADataSource、tenantBDataSource)與 Bean 名稱匹配,Spring 可以解決歧義。但是,這種行為在復雜的配置中並不總是可靠或可預測的,這就是為什麼首選顯式配置(例如 @Qualifier
)。
為什麼 Spring 更傾向於使用 @Qualifier?
使用 @Qualifier
可以確保清晰度並消除歧義,使開發人員和框架都能明確意圖。
示例:
<code>@Autowired public TenantService( @Qualifier("tenantA-dataSource") TenantDataSource tenantADataSource, @Qualifier("tenantB-dataSource") TenantDataSource tenantBDataSource ) { this.tenantADataSource = tenantADataSource; this.tenantBDataSource = tenantBDataSource; }</code>
這樣,Spring 就能準確知道要注入哪些 Bean,而不管參數名稱或其他因素如何。
Spring 應該更智能嗎?
有人可能會認為像 Spring 這樣的框架應該更智能,並在存在歧義時自動將 Bean 名稱與參數名稱匹配。但是:
- 向後兼容性: 自動更改此行為可能會破壞 Bean 名稱和參數名稱不匹配的現有應用程序。
-
可預測性: 顯式地解決歧義(例如,通過
@Qualifier
)確保開發人員始終知道正在註入哪些 Bean。隱式假設可能會導致難以調試的問題,尤其是在大型複雜應用程序中。
真實場景中的情況
在大多數實際應用程序中:
- 開發人員使用有意義的 Bean 名稱和參數名稱,但他們也更喜歡像
@Qualifier
這樣的顯式配置以確保清晰度。 - 對於多實例場景,通常使用動態配置或基於工廠的方法(例如 AbstractRoutingDataSource),而不是手動連接各個 Bean。
關鍵要點
-
Spring 首先按類型注入: 如果只有一種類型的 Bean,Spring 會毫無問題地註入它。如果存在多種相同類型的 Bean,Spring 需要額外的提示(例如
@Qualifier
)來解決歧義。 -
參數名稱不可靠: 默認情況下,參數名稱不會保留在 Java 字節碼中,因此 Spring 無法使用它們將 Bean 與參數匹配。即使保留了參數名稱(
-parameters
),Spring 也會避免隱式基於名稱的匹配,除非明確配置。 -
顯式優於隱式: Spring 優先考慮可預測性,並鼓勵開發人員使用顯式配置(例如
@Qualifier
或@Primary
)而不是依賴於隱式匹配。 - Spring 的設計理念: 歧義錯誤可以防止意外行為,並確保開發人員完全控制依賴注入。
以上是春季 - 為什麼要逐名 - 擬議中的標準的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

公司安全軟件導致部分應用無法正常運行的排查與解決方法許多公司為了保障內部網絡安全,會部署安全軟件。 ...

將姓名轉換為數字以實現排序的解決方案在許多應用場景中,用戶可能需要在群組中進行排序,尤其是在一個用...

系統對接中的字段映射處理在進行系統對接時,常常會遇到一個棘手的問題:如何將A系統的接口字段有效地映�...

在使用MyBatis-Plus或其他ORM框架進行數據庫操作時,經常需要根據實體類的屬性名構造查詢條件。如果每次都手動...

在使用IntelliJIDEAUltimate版本啟動Spring...

Java對象與數組的轉換:深入探討強制類型轉換的風險與正確方法很多Java初學者會遇到將一個對象轉換成數組的�...

電商平台SKU和SPU表設計詳解本文將探討電商平台中SKU和SPU的數據庫設計問題,特別是如何處理用戶自定義銷售屬...

Redis緩存方案如何實現產品排行榜列表的需求?在開發過程中,我們常常需要處理排行榜的需求,例如展示一個�...
