简体   繁体   English

Java Bean 复合注入

[英]Java Bean Composite injection

I have an interface我有一个界面

public interface Abstraction { 
    void execute();
}

I have built a composite implementation and want to registered this object as the bean, @Named我已经构建了一个复合实现,并希望将此对象注册为 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);
    }
}

How do I set it up so that the set of implementations to the abstraction gets injected properly into the Composite above?我如何设置它以便抽象的实现集正确地注入到上面的复合中? I will be having another object that takes the abstraction as a dependency and I want it to receive the @Named Composite above with the 2 Implementations below injected into the ctor.我将拥有另一个将抽象作为依赖项的对象,并且我希望它接收上面的@Named Composite,并将下面的 2 个实现注入到构造函数中。

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

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

If you create a bean for each of your implementations, your example will work out of the box.如果您为每个实现创建一个 bean,您的示例将开箱即用。 For example, annotate your implementations with @Named or @Component and mark them for scanning (component scan their package)例如,使用@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() {
    }
}

The Composite 's list will contain both implementations. Composite的列表将包含这两种实现。

Alternatively, since you only have two implementations, you could name their beans and inject them separately.或者,由于您只有两个实现,您可以命名它们的 bean 并分别注入它们。 For example例如

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

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

and inject them in the Composite并将它们注入Composite

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

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

I suggest this solution just because the order of initialization of Abstraction beans might mess up your context initialization.我建议这个解决方案只是因为Abstraction bean 的初始化顺序可能会弄乱你的上下文初始化。 For example if Implementation1 somehow depended on the initialization of Composite , the context would complain.例如,如果Implementation1以某种方式依赖于Composite的初始化,则上下文会抱怨。 This is rare and you can control it in other ways.这是罕见的,您可以通过其他方式控制它。 Still, being explicit about the beans might be clearer in this case.尽管如此,在这种情况下,明确说明 bean 可能会更清楚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM