[英]Spring JavaConfig - NoSuchBeanDefinitionException: No unique bean of type
[英]In Spring JavaConfig, should the bean return type be the interface or implementation?
當我通過XML配置實現DataSource
(例如HikariCP )的類時,它看起來像這樣:
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close"/>
根據Spring Reference手冊 ,JavaConfig中的相當於:
@Bean (destroyMethod = "close")
public DataSource dataSource () {
return new HikariDataSource();
}
為什么我們在JavaConfig中返回接口類型,特別是在這種情況下, DataSource
沒有close()
方法,但實現確實(並且Spring確實設法找到了close()
方法)?
我找不到應用程序在此配置方法與使用實現類型之間的行為方面的任何差異:
@Bean (destroyMethod = "close")
public HikariDataSource dataSource () {
return new HikariDataSource();
}
即使在考慮自動裝配時,這也不應成為問題,因為兩種返回類型都適用於DataSource
實例變量。 那么返回的正確類型是什么(如果有一個'正確的'),為什么?
我找不到應用程序在此配置方法與使用實現類型之間的行為方面的任何差異
你做對了,沒有任何區別,因為在這兩種情況下最終返回的是new HikariDataSource();
,即HikariDataSource
類的對象。
您的第一種情況更具可伸縮性,因為將來您可以在不更改返回類型的情況下返回DataSource
其他實現。 或者您可以更新該方法以實現Factory設計模式,以根據情況返回大量的DataSource
實現。
那么返回的正確類型是什么(如果有一個'正確的'),為什么?
實際上沒有正確的方法,它完全取決於開發人員但是“編程接口”總是很好的設計。 在你的情況下,因為你返回的東西,所以它不會有太大的區別,但你仍然應該使用public DataSource dataSource ()
。
當你可以創建一個接受某個參數的方法時,程序到接口特別有用,假設public void dataSource (DataSource ds)
,在這種情況下你可以傳遞DataSource
任何實現,所以它是一個很好的設計, 因為它是可擴展的 。
另外,我建議閱讀有關工廠設計模式的內容 ,這是一個很好的接口程序示例 。
你應該返回通用實現。
這就是為什么:
首先,你是對的。 如果您返回impl,您仍然可以自動裝配接口。 所以你可以做到以上,然后:
@Autowire Datasource ds;
但是,你不能這樣做。 您無法返回Datasource並自動裝配HikariDataSource。
為什么這很重要?
您不希望您的實現依賴於特定的實現。 例如:
您編寫了Appcode,所有代碼都依賴於HikariDataSource。 由於這是一個數據源,假設你有400個daos實現了使用它並使用該類的實現特定細節。 現在,如果你改變那個impl,你所有的客戶都會破產。 你將有一段時間讓事情再次發揮作用。 每當你需要改變它時,這將重復出現(請注意,probs不會像數據源那樣經常發生)。
現在返回接口或基類會阻止客戶依賴於特定於實現的詳細信息。 之后您可以快速切換數據源。 只要您實現數據源接口,一切都將繼續工作。
下一個:測試。 您希望為測試提供不同的東西(比方說數據源)。 你真的想為你的測試啟動一個數據庫,而內存數據庫就足夠了嗎? 現在在DAO測試中,如果依賴於IMPL,則無法針對通用數據源(InMemoryDataSource)進行測試。 如果返回界面,則可以使用不同的測試配置來簡化設置。
我希望這有意義/有幫助。
干杯,
阿圖爾
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.