CDI:动态注入一组类如何?

CDI: Dynamical injection of a group of classes how to?

我需要在我的应用程序中动态注入一组 classes。目的是,随着应用程序的增长,只需​​添加更多 classes 继承相同的接口。使用传统的 java 很容易做到这一点,因为我只需要搜索包中的所有 classes 并执行循环来实例化它们。我想在 CDI 中进行。例如:

public MyValidatorInterface {
 public boolean validate();
}

@Named
MyValidator1 implements MyValidatorInterface
...

@Named
MyValidator2 implements MyValidatorInterface
...

现在丑陋的非真实 java 代码只是为了了解我想做什么:

public MyValidatorFactory {
 for (String className: classNames) {
  @Inject
   MyValidatorInterface<className> myValidatorInstance;
  myValidatorInstance.validate();
}
}

我想遍历在 classNames 列表中找到的所有实现(顺便说一句,所有这些都在同一个包中)并动态注入它们,所以如果下周我添加一个新的验证器 MyValidator3,我只需要对新 class 进行编码并将其添加到项目中。 MyValidatorFactory 中的循环会找到它,注入它并在新 class 上执行 validate() 方法。

我读过有关动态注入的内容,但我找不到一种方法来遍历一组 class 名称并注入它们,就像我以前用旧方法实例化它们一样。

谢谢

您所描述的正是 Instance<T> 所做的。

对于上面的示例,您可以:

`@Inject Instance<MyValidatorInterface> allInstances`

现在,allInstances 变量包含所有具有给定类型 (MyValidatorInterface) 的 bean。您可以根据 bean 的限定符 and/or class 调用 select(..) 来进一步缩小集合范围。这将再次 return 一个 Instance 但只有以前适合的 beans 的一个子集。最后,您调用 get() 为您检索 bean 实例。

注意: 如果在上述情况下直接调用 get()(没有 select),您将得到一个异常,因为您有两个 bean给定类型,CDI 无法确定应该使用哪一个。 type-safe 决议的规则暗示了这一点。

您最有可能想知道的是 Instance<T> 也实现了 Iterable,因此这就是您迭代 bean 的方式。你会想做这样的事情:

@Inject 
Instance<MyValidatorInterface> allInstances;

public void validateAll() {
  Iterator<MyValidatorInterface> iterator = allInstances.iterator();
  while (iterator.hasNext()) {
    iterator.next().callYourValidationMethod();
  }}
}