当前位置: 代码迷 >> java >> 尝试将 EJB 注入另一个组件时出现 UnsatisfiedResolutionException 的“不满意的依赖项”
  详细解决方案

尝试将 EJB 注入另一个组件时出现 UnsatisfiedResolutionException 的“不满意的依赖项”

热度:41   发布时间:2023-07-25 20:03:28.0

我正在尝试实现 Java EE 的托管执行程序ManagedExecutorService来提交可调用任务,其中每个任务都会调用注入的 bean 方法。

我正在使用Instance类让容器知道任务对象,但是当get()被执行时,会抛出以下异常:

引起:javax.ejb.EJBException: org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: 不满足类型 MyTask 与限定符 @Default 的依赖关系

我在 WildFly 14 上运行它。

注入的bean:

@Stateless
public class MyBean {

    public void print() {
        System.out.println("MyBean printed");
    }
}

任务:

@Stateless
public class MyTask implements Callable<String> {

    @Inject
    MyBean myBean;

    @Override
    public String call() throws Exception {

        System.out.println("MyTask called");
        myBean.print();
        return "Task called";

    }
}

任务调用者:

@Stateless
public class TestBean {

    @Inject
    Instance<MyTask> myTaskInstance;

    @Resource
    private ManagedExecutorService executor;

    public void test() throws InterruptedException, ExecutionException {

        List<Callable<String>> tasks = new ArrayList<>(); 
        MyTask task = myTaskInstance.get();  // <------- Exception is thrown here
        tasks.add(task);
        MyTask task2 = myTaskInstance.get();
        tasks.add(task2);

        List<Future<String>> taskResults = null;
        taskResults = executor.invokeAll(tasks);

        List<String> results = new ArrayList<>(); 

        for(Future<String> taskResult : taskResults) {
                results.add(taskResult.get());
        }

    }
}

为什么会抛出异常以及如何解决这个问题? 类路径中是否缺少库?

问题在于,使用MyTask作为实现Callable的 EJB,您已经从这个 bean 的“bean 类型”中删除了MyTask类本身,这意味着它不能被注入到@Inject MyTask xxx “client”,根据:

18.2.2. 会话 bean 的 bean 类型

会话 bean 的不受限制的 bean 类型集包含 bean 的所有本地接口及其超接口。 如果会话 bean 具有无接口视图,则不受限制的 bean 类型集包含 bean 类和所有超类。 另外,java.lang.Object 是每个会话 bean 的 bean 类型。

这就是 Weld 找不到有效MyTask bean 来满足注入TestBean客户端的原因。

您可以通过添加@LocalBean注释为MyTask EJB 提供无接口视图,例如:

@Stateless
@LocalBean
public class MyTask implements Callable<String> {

或者,您可以删除implements Callable和重构,如:

public class MyTask {

    @Inject
    MyBean myBean;

    MyCallable callable = new MyCallable();

    public Callable getCallable() {
        return callable;
    }

    private class MyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {

            System.out.println("MyTask called");
            myBean.print();
            return "Task called";
        }
    }
}    

public class TestBean {

    // ...

    MyTask task = myTaskInstance.get(); 
    tasks.add(task.getCallable())

    // ...
}

有关无接口视图的快速参考,请参见,以及有关更多讨论的文章。