【问题标题】:CDI: Dynamical injection of a group of classes how to?CDI:如何动态注入一组类?
【发布时间】:2017-01-18 09:27:47
【问题描述】:

我需要在我的应用程序中动态注入一组可变的类。目的是,随着应用程序的增长,只需​​要添加更多继承相同接口的类。这对于传统的 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 列表中的所有实现(顺便说一句,所有实现都在同一个包中)并动态注入它们,所以如果下周我添加一个新的验证器 MyValidator3,我只需编写新类并添加它到项目。 MyValidatorFactory 中的循环会找到它,注入它并在新类上执行 validate() 方法。

我已阅读有关动态注入的信息,但我找不到一种方法来循环一组类名并注入它们,就像我以前用旧方法实例化它们一样。

谢谢

【问题讨论】:

标签: java dependency-injection cdi dynamic-loading


【解决方案1】:

您所描述的是Instance&lt;T&gt; 所做的。

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

`@Inject Instance<MyValidatorInterface> allInstances`

现在,allInstances 变量包含所有具有给定类型 (MyValidatorInterface) 的 bean。您可以通过基于限定符和/或 bean 类调用 select(..) 来进一步缩小集合范围。这将再次返回一个Instance,但只有一部分以前适合的bean。最后,您调用 get() 为您检索 bean 实例。

注意:如果您在上述情况下立即调用get()(没有select),您将收到异常,因为您有两个给定类型的bean,而CDI 无法确定哪一个应该使用。这是类型安全解析规则所暗示的。

您最可能想知道的是,Instance&lt;T&gt; 也实现了Iterable,所以这就是您迭代 bean 的方式。你会想做这样的事情:

@Inject 
Instance<MyValidatorInterface> allInstances;

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

【讨论】:

  • 没想到这么简单。以这种方式编码并完美运行。我只是添加了带有 @Named 注释的类,继承了公共接口,它们都包含在迭代器中。谢谢。
  • 很高兴我能帮上忙
猜你喜欢
  • 2015-06-27
  • 2016-02-08
  • 2023-03-10
  • 1970-01-01
  • 2014-04-27
  • 2012-08-05
  • 1970-01-01
  • 2018-02-04
  • 2021-05-03
相关资源
最近更新 更多