编程语言
首页 > 编程语言> > java – 将请求范围数据传递给CDI中的异步方法

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

作者:互联网

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

在Web过滤器中,数据(例如令牌)被设置为RequestScoped CDI bean.稍后我们想要访问这些数据.如果我们在一个线程中工作,一切正常.但如果需要异步运行代码,则会出现问题. CDI注入空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方法访问当前用户令牌(CurrentUserService#token).结果我们将收到null.

预计“请求作用域”数据应该可以从请求范围内执行的任务中访问.应该使用类似InheritableThreadLocal的东西来评估来自新线程的原始线程数据.

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

提前致谢.

解决方法:

根据Java EE Con​​currency Utilities规范的§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,asynchronous,cdi,wildfly,java-ee-7
来源: https://codeday.me/bug/20190623/1270948.html