Java Bean 复合注入

Java Bean Composite injection

我有接口

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 中?我将拥有另一个将抽象作为依赖项的对象,我希望它接收上面的 @Named 组合以及下面注入 ctor 的 2 个实现。

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

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

如果您为每个实现创建一个 bean,您的示例将开箱即用。例如,使用 @Named@Component 注释您的实现并将它们标记为扫描(组件扫描它们的包)

@Configuration
@ComponentScan
public class Whosebug {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Whosebug.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 bean 的初始化顺序可能会扰乱您的上下文初始化。例如,如果 Implementation1 以某种方式依赖于 Composite 的初始化,上下文就会报错。这种情况很少见,您可以通过其他方式控制它。不过,在这种情况下,明确说明 bean 可能会更清楚。