Java EE 7 - 注入Runnable / Callable对象

问题描述 投票:9回答:2

并发实用程序(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查找,但有没有正确的方法如何做到这一点?

java concurrency dependency-injection java-ee-7
2个回答
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的每个实例。


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();
            ...
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.