java - 将请求范围数据传递给 CDI 中的异步方法

标签 java asynchronous cdi wildfly java-ee-7

Java EE 7 应用程序在 Wildfly 9.0.2.Final 上运行。从@Asynchronous 方法中访问请求范围内的数据存在问题。

在 Web 中,过滤器数据(例如 token )被设置到 RequestScoped CDI bean 中。稍后我们要访问此数据。如果我们在一个线程中工作,一切正常。但是如果需要异步运行代码就会出现问题。 CDI注入(inject)空bean,请求数据丢失。

例子如下:

@RequestScoped
public class CurrentUserService implements Serializable {
  public String token;
}

@Stateless
public class Service {
   @Inject
   private RestClient client;

    @Resource
    private ManagedExecutorService executorService;

    @Resource
    private ContextService contextService;

    @Asynchronous
    private <T> Future<T> getFuture(Supplier<T> supplier) {
        Callable<T> task = supplier::get;
        Callable<T> callable = contextService.createContextualProxy(task, Callable.class);
        return executorService.submit(callable);
    }

   public String getToken() throws Exception {
      return getFuture(client::getToken).get();
   }
}

@ApplicationScoped
public class RestClient {
    @Inject
    private CurrentUserService currentUserBean;

    public String getToken() {
        return currentUserBean.token;
    }
}

在给定的示例中,我们希望通过异步 Service.getToken 方法访问当前用户 token (CurrentUserService#token)。结果我们将收到 null。

在请求范围内执行的任务应该可以访问“请求范围”数据。应该使用类似 InheritableThreadLocal 的东西来允许从新线程评估原始线程数据。

这是一个错误吗?可能是我做错了什么?如果是 - 将此类数据传播到异步调用的正确方法是什么?

提前致谢。

最佳答案

根据 Java EE 并发实用程序规范的 §2.3.2.1,您不应尝试这样做:

  • Tasks that are submitted to a managed instance of ExecutorService may still be running after the lifecycle of the submitting component. Therefore, CDI beans with a scope of @RequestScoped, @SessionScoped, or @ConversationScoped are not recommended to use as tasks as it cannot be guaranteed that the tasks will complete before the CDI context is destroyed.

无论您使用并发实用程序还是@Asynchronous 方法,您都需要收集请求范围内的数据并将其传递给您的异步任务。

关于java - 将请求范围数据传递给 CDI 中的异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34417633/

相关文章:

ios - 为什么 completionHandler block 没有响应?

java - 获取 cdi 托管 bean 的真实类名

java - CDI + Java EE 7 中的托管并发

java - 修复自定义 OpenNLP NER 模型

java - SecurityManager.checkPropertyAccess 为现有系统属性抛出 AccessControlException

Java+线程控制方法

java - Java中向下转型类与向下转型接口(interface)的区别?

node.js - Node Js中如何选择首先调用哪个函数

asynchronous - 在 F# 中优化映射异步序列的语法

java - 当 @ApplicationScoped 注入(inject)到另一个类中时,@ApplicationScoped bean 中具有不同作用域的依赖项是否会再次重新注入(inject)?