簡體   English   中英

春豆接線

[英]Spring Bean Wiring

我正在學習Spring的基礎知識,現在我正在研究Beans /接線。 這個問題可能沒有意義,這只是我在閱讀/嘗試Craig Walls的“Spring into Action”一書中的一些例子之后想到的。 說有這個界面。

public interface CompactDisc {
    void play()
}

我有兩個實現此接口的類。

public class HybridTheory implements CompactDisc { }
public class Meteora implements CompactDisc { }

我的配置類使用組件掃描並從這兩個類創建bean。 現在,如果我有一個具有光盤實例的測試類,並使用自動連接進行連線

public class myTest {
    @Autowired
    private CompactDisc cd;
}  

會有問題嗎? 我的問題是,你如何連接它,以便它使用一個bean而不是另一個? 或者這不是真實情況/我應該創建特定類的屬性,而不是接口的屬性? 我想我只是難以繞着布線纏繞我的腦袋。

每當遇到有多個實現相同接口的情況時,您可以采取的方法很少。

1.使用@Qualifier注釋

如果您使用類路徑掃描,您的類可能如下所示:

@Component
public class HybridTheory implements CompactDisc { }

@Component
public class Meteora implements CompactDisc { }

每個Spring bean都獲取一個由容器分配的id,默認情況下它是一個以較小字母開頭的類名。 如果這兩個組件將是:

  • hybridTheory
  • meteora

您可能還希望通過將name參數傳遞給@Component注釋來選擇自定義名稱,例如: @Component("myFavLinkinParkAlbum")

然后,每當你自動裝配CompactDisc bean時,你都可以傳遞@Qualifier注釋並告訴Spring你想到的是哪個bean。

@Service
class Player {
    private final CompactDisc compactDisc;

    // note that starting from Spring 4.3 
    // you can omit @Autowired annotation from constructor
    Player(@Qualifier("hybridTheory") CompactDisc compactDisc) {
        this.compactDisc = compactDisc;
    }
}

2.將您的一個bean標記為@Primary

如果在大多數注射點注射總是相同的豆而另一個很少使用,您可以考慮使用@Primary標記前者。

@Component
@Primary
public class HybridTheory implements CompactDisc { }

每當Spring發現有多個bean匹配注入點時,它將注入一個用@Primary注釋的bean 請注意,如果有多個使用@Primary注釋的bean並且實現了注入點中使用的接口,問題仍然存在。

3.使用Java配置

雖然@Qualifier@Primary有時會解決問題,但您可能會發現要了解注入了哪些實現,您需要通過源代碼大量旅行。 有時候更干凈的方法是從中刪除@Component (或其他構造型注釋)並使用Java配置聲明bean:

public class HybridTheory implements CompactDisc { }

public class Meteora implements CompactDisc { }

@Configuration
class RecordsConfiguration {

    @Bean
    CompactDisc hybridTheory() {
        return new HybridTheory();
    }

    @Bean
    CompactDisc meteora() {
        return new Meteora();
    }

    @Bean
    Player player() {
        return new Player(meteora());
    }
}

選擇最適合您用例的產品!

一種簡單而優雅的方法是盡可能使用byType 當那是不可能的,可以使用的綽號方法。

使用它的一種方法是手動命名bean - 然后在更改類名后bean名稱不會有所不同。 請注意,只有在具有相同類型的多個實現時才應使用命名bean,否則不需要命名。 在下面的示例中,命名是注釋的一部分,例如@Component("hybridTheory") 這意味着您可以將HybridTheory的類名HybridTheory為您想要的任何名稱,並且bean名稱仍然是hybridTheory

當您通過名稱注入某些內容時 ,可以使用@Qualifier批注指定所需的命名bean。 我個人更喜歡@Resource因為你可以在構造函數中使用@Qualifier (我更喜歡構造函數注入而不是基於setter和field的注入)。

應該注入的具體類型-這就是依賴注入是怎么一回事。 其他人(即Spring)將為您處理對象創建;)

public interface CompactDisc {
    void play();
}

@Component
class CompactDiscPlayer {
    @Autowired
    CompactDiscPlayer(@Qualifier("hybridTheory") final CompactDisc compactDisc) {
        // The bean of type HybridTheory will be used
        compactDisc.play();
    }
}

@Component("hybridTheory")
class HybridTheory implements CompactDisc {
    public void play() {
        System.out.println(getClass().getSimpleName());
    }
}

@Component("meteora")
class Meteora implements CompactDisc {
    public void play() {
        System.out.println(getClass().getSimpleName());
    }
}

Spring的文檔描述了各種選項在這里

暫無
暫無

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

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