我需要在我的应用程序中动态注入(inject)一组变量。目的是,随着应用程序的增长,只需添加更多继承相同接口(interface)的类。这对于传统的 java 来说很容易做到,因为我只需要搜索包中的所有类并执行循环来实例化它们。我想在 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 列表中找到的所有实现(顺便说一句,所有实现都将位于同一个包中)并动态注入(inject)它们,因此如果下周我添加一个新的 validator MyValidator3,我只需编写新类并添加它到项目中。 MyValidatorFactory 中的循环将找到它、注入(inject)它并在新类上执行 validate() 方法。
我已经阅读过有关动态注入(inject)的内容,但我找不到一种方法来循环一组类名并注入(inject)它们,就像我以前用旧方法实例化它们一样。
谢谢
最佳答案
您所描述的是Instance<T>
确实如此。
对于上面的示例,您将执行以下操作:
`@Inject Instance<MyValidatorInterface> allInstances`
现在,allInstances
变量包含具有给定类型( MyValidatorInterface
)的所有 bean。您可以通过调用 select(..)
进一步缩小集合范围。基于 Bean 的限定符和/或类别。这将再次返回 Instance
但只有之前拟合的 beans 的一个子集。最后,您调用get()
它会为您检索 bean 实例。
注意:如果您调用 get()
在上述情况下,立即(没有 select
),您将得到一个异常,因为您有两个给定类型的 bean,并且 CDI 无法确定应该使用哪一个。这是类型安全解析规则所暗示的。
您最可能想知道的是 Instance<T>
还实现 Iterable
这就是您迭代 bean 的方式。你会想做这样的事情:
@Inject
Instance<MyValidatorInterface> allInstances;
public void validateAll() {
Iterator<MyValidatorInterface> iterator = allInstances.iterator();
while (iterator.hasNext()) {
iterator.next().callYourValidationMethod();
}}
}
关于java - CDI:如何动态注入(inject)一组类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41715616/