7

我正在实现一个应用程序范围的服务(要进一步注入 JAX-RS/JAX-WS 服务或 servlet,没关系),这将通过 ManagedExecutorService 或 ManagedThreadFactory 产生一些处理。在处理代码(一个 Runnable 实例)内部,我想使用注入的资源,如 EntityManager、DataSource 和 Web 服务引用。第一个解决方案是这样的:

@ApplicationScoped
class MyService {

 @Resource private ManagedExecutorService mes;

 public void request(String param) {
  mes.submit(new MyTask(param));
 }

}

class MyTask implements Runnable {
 // constructor skipped
 @Resource private DataSource ds;

 public void run() {
  // do processing
 }

}

在 MyTask.run() 中,该ds字段似乎为空。好的,这是因为 MyTask 实例不是托管 bean,即它不是由 DI 容器创建的,因此无法对其进行注入。让我们将直接实例化更改为上下文实例:

@ApplicationScoped
class MyService {

 @Resource ManagedExecutorService mes;
 @Inject private Instance<MyTask> instance;

 public void request(String param) { // <- no way to pass param to MyTask()!
  mes.submit(instance.get());
 }

}

这可以按需要工作。但这是实现我想要的正确/最佳方式吗?通常,问题是,如何在运行时按需创建注入/托管实例。此外,在后一种情况下,我无法将任何参数传递给 MyTask 构造函数——这可能吗,还是我必须引入 MyTask.setParam() 方法来配置 MyTask 的实例?

4

1 回答 1

2

CDI 规范禁止向构造函数传递参数 - 容器只能调用默认构造函数或带有 注释的构造函数@Inject,请参阅CDI 规范 - 3.1.1。哪些 Java 类是托管 bean。所以是的,你必须在这里介绍 setter。

于 2013-11-14T09:14:51.940 回答