簡體   English   中英

Spring,基於注釋,覆蓋組件

[英]Spring, annotation based, overriding of components

當我使用XML設置Spring時,可以覆蓋稍后加載的XML文件中的組件定義。 它對於測試非常有用 - 我創建默認配置集,然后使用添加測試配置加載它,用一些特殊部分替換某些組件(存根,模擬等)。 現在我開始遷移到基於注釋的配置,這會導致一些問題。

使用注釋的直接方法是使用@Component自動發現包

所以我有

@Configuration
@ComponentScan({"some.pack1", "some.pack2"})
public class ProductConfig{}

當@Configuration @Import({ProductConfig.class})@ComponentScan({“test.pack”})公共類TestConfig {}時

但是如果我嘗試覆蓋test.pack中的組件,它將導致沖突

而我能做什么?

經過一些調查,其中有3個答案,其中有一些問題

  1. 最糟糕 - 我可以在ComponentScan上使用@Filter - 這是最糟糕的方式,
    • 我不能導入現有的配置(可以有一些額外的bean)
    • 我必須重新掃描所有組件,並明確定義一組過濾器
  2. 我可以使用@Profile和activeProfiles - 它更好,雖然它更復雜,但是,但是
    • 這意味着我必須在產品類中知道在某些測試中它們可以被禁用
  3. 不要在覆蓋Config時使用@ComponentScan並使用@Bean
    • 它可能在測試配置上很好,但這意味着我失去了使用@Component注釋的能力
  4. 在上下文中使用setParent - 它運行良好,但是
    • 它對ApplicationContext的實現沒有在接口上的顯式操作
    • 如果覆蓋服務對來自覆蓋配置的某些組件具有@Autwire依賴性,則不難設置 - 需要手動注冊和刷新

什么是覆蓋配置的最佳和標准方法??? 當我使用基於XML的時候,這不是問題......

@profile在為您的服務/代碼實施測試策略時起着至關重要的作用。

例如,在開發中,您可能具有:

public interface DataSource{
 public String getHost();
}

默認實現是

@Component
@Profile("Prod") 
public class DevDataSource implements DataSource {
    public String getHost(){
     // return actual value
}

和組件測試的實現(假冒)

@Component
@Profile("test") 
public class StubbyDataSource implements DataSource {
    public String getHost(){
     return "some-host";   // return mocked data
}

現在你可以在這里編寫一個測試,它可以作為集成測試單元測試組件測試https://martinfowler.com/bliki/ComponentTest.html

這樣,您的測試策略將更加優雅,簡潔且易於維護。 只需更改配置文件 ,相同的測試就可以指向不同的環境(真實或虛假)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM