You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Payara Micro中@Asynchronous注解未实现异步执行问题

问题原因

你的@Asynchronous注解未生效,核心原因是JAX-RS资源类默认不属于EJB容器管理的Bean,直接调用自身标注@Asynchronous的方法时,只是普通的同步方法调用,不会触发容器的异步代理逻辑,自然无法实现异步执行。

解决方案

方案一:将资源类转为无状态EJB

给FooResource添加@Stateless注解,让它成为EJB容器管理的Bean,此时容器会为其生成代理,调用异步方法时会触发异步逻辑:

@Path("foo")
@Stateless
public class FooResource {
  @GET
  public String get() {
    System.out.println("Request started");
    this.doSomething(); // 现在会通过EJB代理实现异步
    System.out.println("Request ended");
    return "Hello world! ";
  }

  @Asynchronous
  public void doSomething() {
    try {
      System.out.println("Long task started");
      Thread.sleep(2000);
      System.out.println("Long task ended");
    } catch (InterruptedException e) {
      System.out.println("Long task failed");
    }
  }
}

方案二:将异步方法抽入独立EJB

如果不想修改资源类的类型,可以把异步方法单独放到一个EJB类中,再通过依赖注入调用:

  1. 创建异步业务EJB:
@Stateless
public class AsyncService {
  @Asynchronous
  public void doSomething() {
    try {
      System.out.println("Long task started");
      Thread.sleep(2000);
      System.out.println("Long task ended");
    } catch (InterruptedException e) {
      System.out.println("Long task failed");
    }
  }
}
  1. 修改资源类注入并调用:
@Path("foo")
public class FooResource {
  @Inject
  private AsyncService asyncService;

  @GET
  public String get() {
    System.out.println("Request started");
    asyncService.doSomething(); // 通过注入的EJB触发异步执行
    System.out.println("Request ended");
    return "Hello world! ";
  }
}
注意事项
  • Payara Micro默认支持EJB与JAX-RS的集成,无需额外配置domain.xml,但若你对domain.xml做过自定义修改,需确保ejb-container组件处于启用状态。
  • 永远不要直接调用自身的异步方法,因为这种调用不会经过容器代理,容器无法识别并处理@Asynchronous注解。

内容的提问来源于stack exchange,提问作者Calcimicium

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 08:35:18