如何在RESTEasy Reactive中结合Qute执行阻塞操作?
问题解决方案
问题1:依赖冲突导致构建失败
quarkus-resteasy-qute是基于传统阻塞式RESTEasy的依赖,而你已使用RESTEasy Reactive(quarkus-resteasy-reactive),两者都提供io.quarkus.rest能力,引发冲突。正确做法是使用RESTEasy Reactive对应的Qute依赖:quarkus-resteasy-reactive-qute,也就是你尝试的第二种方式,接下来解决该方式下的阻塞操作异常。
问题2:IO线程执行阻塞操作抛出异常
RESTEasy Reactive默认将请求处理放在IO线程上,而Hibernate ORM Panache的阻塞式仓库方法属于阻塞操作,不能在IO线程执行,否则触发BlockingOperationNotAllowedException。提供两种解决方法:
方法1:用@Blocking注解标记REST方法
在Rest Controller方法上添加@Blocking注解,让方法在worker线程执行,允许阻塞操作:
import io.quarkus.vertx.web.Blocking; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import io.quarkus.qute.Template; import io.quarkus.qute.TemplateInstance; @Path("/items") public class ItemController { private final Template items; private final ItemRepository repository; public ItemController(Template items, ItemRepository repository) { this.items = items; this.repository = repository; } @GET @Blocking // 添加该注解 public TemplateInstance getItems() { var itemsList = repository.listAll(); return items.data("items", itemsList); } }
方法2:将阻塞操作包装到响应式Uni中指定线程池
若不想用@Blocking,可将阻塞操作包装到Uni中,指定在worker线程执行:
import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import io.quarkus.qute.Template; import io.quarkus.qute.TemplateInstance; import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.infrastructure.Infrastructure; @Path("/items") public class ItemController { private final Template items; private final ItemRepository repository; public ItemController(Template items, ItemRepository repository) { this.items = items; this.repository = repository; } @GET public Uni<TemplateInstance> getItems() { return Uni.createFrom().item(() -> repository.listAll()) .runSubscriptionOn(Infrastructure.getDefaultWorkerPool()) .map(itemsList -> items.data("items", itemsList)); } }
补充说明
- 优先推荐
@Blocking注解,简洁直观,适合传统阻塞逻辑的迁移场景。 - 若后续计划全面转向响应式,可考虑用
PanacheRepositoryReactive替代阻塞式PanacheRepository,从根源避免阻塞操作问题。
内容的提问来源于stack exchange,提问作者Dario Scoppelletti
相关产品推荐
相关产品推荐

