Spring Boot 3.2.x中@AfterReturning无法接收Kotlin suspend函数返回值咨询
Spring Boot 3.2+中@AfterReturning处理Kotlin Suspend函数返回值变为MonoOnErrorResume的问题
问题原因
这是Spring Framework 6.1(对应Spring Boot 3.2及以上版本)对协程方法AOP处理的行为变更,并非支持终止。
在Spring Boot 3.1.x(基于Spring Framework 6.0)中,AOP会自动解包suspend函数返回的响应式包装对象(如Mono),直接把实际业务返回值传递给@AfterReturning的切面方法;而Spring Framework 6.1优化了协程与响应式流的协作逻辑,不再自动解包,而是直接将包装后的响应式实例(如MonoOnErrorResume)传递给切面。
解决方案
针对这个变更,有两种常见的处理方式:
1. 手动解包响应式对象
在切面方法中判断返回值类型,手动处理Mono/Flux以获取实际业务返回值:
@AfterReturning("execution(* x.x.x.suspendFun(..))", returning = "response") fun controllerSuccessLogging(joinPoint: JoinPoint, response: Any) { when (response) { is Mono<*> -> { response.doOnNext { actualResponse -> logger.info("实际返回值: $actualResponse") }.subscribe() } is Flux<*> -> { response.doOnNext { actualItem -> logger.info("流中返回项: $actualItem") }.subscribe() } else -> logger.info("返回值: $response") } }
注意:如果在非协程调度线程中调用
block()可能会引发阻塞问题,推荐使用响应式的doOnNext等操作符处理。
2. 调整切点与方法返回值定义
如果你的suspend函数原本返回的是自定义业务类型(而非Mono/Flux),可以检查是否是Spring WebFlux自动将其包装为响应式类型。这种情况下,可以考虑:
- 明确方法返回类型为
Mono<GetTestResponse>,在切面中直接处理Mono; - 若不需要响应式包装,确保配置正确,避免Spring自动转换。
补充说明
这个变更的核心是Spring Framework 6.1对协程支持的优化,目的是让AOP处理更贴近响应式流的原生行为,减少自动解包带来的潜在线程调度问题,并非取消对suspend函数的AOP支持。
内容的提问来源于stack exchange,提问作者jun
相关产品推荐
相关产品推荐

