2016-04-27 54 views
1

我有一個接口Java Bean的複合注

public interface Abstraction { 
    void execute(); 
} 

我建立了一個複合的實現,想註冊這個對象作爲bean,@Named

@Named 
public class Composite implements Abstraction { 
    private List<Abstraction> list; 

    @Inject 
    public Composite(List<Abstraction> list) { 
     this.list = list; 
    } 

    public void execute() { 
     list.forEach(Abstraction::execute); 
    } 
} 

如何設置它,以便抽象實現的集合被正確注入到上面的Composite中?我將擁有另一個將抽象視爲依賴關係的對象,並且我希望它將上面的2個實現注入到ctor中,以獲得上面的@Named複合。

public class Implementation1 implements Abstraction { 
    public void execute() { } 
} 

public class Implementation2 implements Abstraction { 
    public void execute() { } 
} 
+0

它會一直是兩個嗎?只需按名稱分別注入它們。 – Savior

+0

@Pillar這是我特殊的情況,我可以做到這一點,但不知道如何,因爲我不能在每個實現上放置'Named'註釋。對不起,我是新來的Java豆世界。 –

回答

1

如果您爲每個實現創建一個bean,您的示例將開箱即用。例如,你的註釋與實現或@Named@Component它們標記爲掃描(掃描組件其包裝)

@Configuration 
@ComponentScan 
public class StackOverflow { 
    public static void main(String[] args) throws Exception { 
     AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(StackOverflow.class); 
     System.out.println(ctx.getBean(Composite.class).list); 
    } 
} 

interface Abstraction { 
    void execute(); 
} 

@Named 
class Composite implements Abstraction { 
    List<Abstraction> list; 

    @Inject 
    public Composite(List<Abstraction> list) { 
     this.list = list; 
    } 

    public void execute() { 
     list.forEach(Abstraction::execute); 
    } 
} 

@Named 
class Implementation1 implements Abstraction { 
    public void execute() { 
    } 
} 

@Named 
class Implementation2 implements Abstraction { 
    public void execute() { 
    } 
} 

Composite的列表將包含兩種實現。

另外,由於您只有兩個實現,您可以命名它們的bean並單獨注入它們。例如

@Component("one") 
class Implementation1 implements Abstraction { 
    public void execute() { 
    } 
} 

@Component("two") 
class Implementation2 implements Abstraction { 
    public void execute() { 
    } 
} 

,並注入他們在Composite

List<Abstraction> list = new ArrayList<>(2); 

@Inject 
public Composite(@Qualifier("one") Abstraction one, @Qualifier("two") Abstraction two) { 
    list.add(one); 
    list.add(two); 
} 

我建議這種解決方案只是因爲Abstraction豆可能弄亂你的上下文初始化初始化的順序。例如,如果Implementation1以某種方式取決於Composite的初始化,則上下文會抱怨。這很少見,你可以用其他方式控制它。儘管如此,在這種情況下,清楚地瞭解這些bean可能會更清楚。

+0

你的第一個場景適用於我的情況,我不在乎爲我的複合材料填充抽象列表的順序。但是我看到,當複合bean被創建時,它實際上還有其他2個實現,但是當另一個bean試圖創建依賴於'Abstraction'的時候,它會如何知道它應該注入組合?在這種情況下,我得到一個錯誤:'預計單個匹配的bean,但發現3:implementation2,composite,implementation1' –

+0

@JonErickson您需要使用名稱限定它,並在注入點使用該名稱。或者,定義一個單獨的接口,它是'Abstraction'的子類型(比如'CompositieAbstract'),'Composite'實現它並且注入它。 – Savior

+0

gotcha,我爲組合添加了一個Named(「composite」)註釋,然後將Qualifier(「composite」)註釋添加到另一個對象的構造函數參數中。謝謝你的幫助 –