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 可能会更清楚。
我有接口
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 可能会更清楚。