【问题标题】:Java EE 7 - Injection into Runnable/Callable objectJava EE 7 - 注入可运行/可调用对象
【发布时间】:2014-01-31 10:49:09
【问题描述】:

Java EE 7 中引入了并发实用程序 (JSR 236)。

有什么方法可以将我的 EJB 注入 Runnable/Callable 对象?

特别是我想要这样的东西:

带有业务逻辑的ejb

@LocalBean
public class MyEjb {
    public void doSomeStuff() {
        ... do some stuff ...
    }
}

我想在其中注入 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 字段始终为空。我想这可以帮助 JNDI 查找,但是有什么正确的方法可以做到这一点吗?

【问题讨论】:

标签: java concurrency dependency-injection java-ee-7


【解决方案1】:

您必须让容器有机会将 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 的每个实例。

【讨论】:

  • 它给出“org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308: Unable to resolve any beans for Type ...”异常
  • @ravthiru - 您需要确保传入的 bean 由容器管理。例如。在声明类之前添加“@ManagedBean”。
  • 我仍然收到 UnsatisfiedResolutionException 异常
  • 您能否解释一下为什么会这样:“@Inject Instance myTaskInstance;”,但不能:“@Inject MyTask myTaskInstance;”?为什么我需要使用 Instance 对象?
【解决方案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();
            ...
        }
    }
}

【讨论】:

    猜你喜欢
    • 2016-02-22
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 2014-01-19
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    相关资源
    最近更新 更多