2016-04-27 38 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”)注释添加到另一个对象的构造函数参数中。谢谢你的帮助 –