簡體   English   中英

按接口自動裝配 bean,但在注入時排除特定 bean

[英]Autowire beans by interface but exclude specific bean at injection time

我目前正在注入一個 Spring @Component列表,它們都實現了相同的接口。 這很好用,但是我想將這個相同的列表注入到該列表中的一個 bean 的實例中,這樣我就可以對該列表中的所有其他 bean 采取行動。 我看不到如何從該注入中排除特定的 bean,我可以在注入后過濾列表,但這當然會在啟動時導致 Spring 循環依賴異常。 我的問題是我可以在注入時告訴 spring 從 bean 列表中排除注入的 class 嗎?

public interface Foo {
    String doSomething();
}
@Component
public class Foo1 implements Foo {

    private final List<Foo> foos;

    public Sample(final List<Foo> foos) {
        //Don't include Foo1
        this.foos = foos;
    }

    public String doSomething() {
        foos.forEach(foo -> foo.doSomething());
        return "aString";
    }
}

@Component
public class Foo2 implements Foo {

    private final List<Foo> foos;

    public Sample(final List<Foo> foos) {
        //Don't include Foo2
        this.foos = foos;
    }

    public String doSomething() {
        foos.forEach(foo -> foo.doSomething());
        return "anotherString";
    }
}
@Component
public class Foo3 implements Foo {
//and so on

我同意@robertobatts 的觀點,它看起來確實像一個反模式,你應該避免它。 如果您可以澄清問題背景,也許我們可以幫助您以更好的方法來實現您想要實現的目標!

這個解決方案幾乎是一個 hack,除非真的有必要,否則我不建議使用它。 您可以在@Configuration class 中將其定義為 @Configuration Foo2 ,而不是將其聲明為組件,方法是將ListableBeanFactory作為 bean 定義方法中的參數注入,然后使用它的getBeansOfType方法過濾掉您實際需要實例化Foo2 bean 的Foo實現。

所以你的 Foo2 class 看起來像

public class Foo2 implements Foo {

    private final List<Foo> foos;

    public Foo2(final List<Foo> foos) {
        this.foos = foos;
    }

    public String doSomething() {
        foos.forEach(foo -> foo.doSomething());
        return "anotherString";
    }
}

並且配置 class 看起來像

@Configuration
public class MyConfiguration {

    @Bean
    Foo2 foo2(ListableBeanFactory bf) {
        final Map<String, Foo> fooBeans = bf.getBeansOfType(Foo.class);
        List<Foo> foos = // filter out what you don't need from fooBeans
        return new Foo2(foos);
    }

}

您可以在doSomething方法中查找所有Foo類型的 bean,然后排除當前的,而不是在構造函數中注入列表。 要查找,請使用BeanFactoryUtils中的任何方法,例如beanNamesForTypeIncludingAncestors ,然后排除foo1 ,這是 class Foo1的 bean 名稱。 查找甚至可以編碼為接口Foo中的默認方法。

暫無
暫無

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

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