我正在实现一个应用程序范围的服务(要进一步注入 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 的实例?