Concurrency Utilities(JSR 236)已在Java EE 7中引入。
有没有办法将我的EJB注入Runnable / Callable对象?
具体来说,我想要这样的事情:
带有业务逻辑的ejb
@LocalBean
public class MyEjb {
public void doSomeStuff() {
... do some stuff ...
}
}
runnable / callable class我想要注入MyEjb的实例
public class MyTask implements Runnable {
@EJB
MyEjb myEjb;
@Override
public void run() {
...
myEjb.doSomeStuff();
...
}
}
启动新任务的对象
@Singleton
@Startup
@LocalBean
public class MyTaskManager {
@Resource
ManagedExecutorService executor;
@PostConstruct
void init() {
executor.submit(new MyTask());
}
}
MyTask中的myEjb字段始终为null。我想可以帮助JNDI查找,但是有什么方法可以做到这一点吗?
答案 0 :(得分:7)
您必须为容器提供将EJB注入Task实例的机会。您可以使用此代码中的动态实例来执行此操作:
@Stateless
public class MyBean {
@Resource
ManagedExecutorService managedExecutorService;
@PersistenceContext
EntityManager entityManager;
@Inject
Instance<MyTask> myTaskInstance;
public void executeAsync() throws ExecutionException, InterruptedException {
for(int i=0; i<10; i++) {
MyTask myTask = myTaskInstance.get();
this.managedExecutorService.submit(myTask);
}
}
因为您不是使用new运算符而是通过CDI的实例机制创建实例,所以容器在调用myTaskInstance.get()
时会准备MyTask的每个实例。
答案 1 :(得分:2)
如果MyTask实例是由您创建的,则无法注入EJB,因为Container只知道自己创建的实例。相反,您可以在MyTaskManager Singleton SB中注入EJB,并将MyTask Runnable类定义为内部类,如下所示:
@Singleton
@Startup
@LocalBean
public class MyTaskManager {
@Resource
ManagedExecutorService executor;
@EJB
MyEjb myEjb;
@PostConstruct
void init() {
executor.submit(new MyTask());
}
class MyTask implements Runnable {
@Override
public void run() {
...
myEjb.doSomeStuff();
...
}
}
}