CDI +在Java EE 7中管理并发

Dim*_*tri 6 java java-ee cdi java-ee-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
 }

}
Run Code Online (Sandbox Code Playgroud)

在MyTask.run()内部,该ds字段显示为null.好的,这是因为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());
 }

}
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*sik 2

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