AsyncHandlerMethodReturnValueHandler 异步与同步返回值设计案例说明
AsyncHandlerMethodReturnValueHandler
它用于处理异步方法返回值的特殊情况。当控制器方法使用 DeferredResult
或 Callable
来处理异步逻辑时,这个接口允许开发者介入返回值的处理过程。
业务场景:
假设你正在开发一个需要长时间处理的 API,例如,处理大量数据的分析或等待外部服务的响应。你希望在处理过程中能够异步地返回结果,而不是阻塞服务器的线程。
1. 创建自定义的 AsyncHandlerMethodReturnValueHandler
:
import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
import org.springframework.web.context.request.NativeWebRequest;
public class CustomAsyncHandlerMethodReturnValueHandler extends AsyncHandlerMethodReturnValueHandler {
@Override
public boolean supportsReturnType(MethodParameter returnType) {
// 确定是否支持返回值的类型
return returnType.getParameterType().equals(CustomAsyncResponseType.class);
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
// 自定义异步处理逻辑
if (returnValue instanceof CustomAsyncResponseType) {
CustomAsyncResponseType asyncResponse = (CustomAsyncResponseType) returnValue;
// 可以设置超时时间、注册回调等
webRequest.setAttribute("customAsyncResponse", asyncResponse, 0);
// 异步处理完成后,结果将被存储并返回
}
}
}
2. 注册自定义的 AsyncHandlerMethodReturnValueHandler
:
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
returnValueHandlers.add(new CustomAsyncHandlerMethodReturnValueHandler());
}
}
3. 使用自定义的 AsyncHandlerMethodReturnValueHandler
:
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;
@RestController
public class AsyncController {
@GetMapping("/async-operation")
public DeferredResult<CustomAsyncResponseType> performAsyncOperation() {
DeferredResult<CustomAsyncResponseType> output = new DeferredResult<>(10000L); // 设置超时时间
// 启动异步操作
new Thread(() -> {
try {
// 模拟长时间运行的任务
Thread.sleep(5000);
output.setResult(new CustomAsyncResponseType(/* 响应数据 */));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
output.setErrorResult(new CustomAsyncResponseType(/* 错误信息 */));
}
}).start();
return output;
}
}
关键处理代码:
supportsReturnType
方法:确定当前AsyncHandlerMethodReturnValueHandler
是否支持给定的返回值类型。handleReturnValue
方法:处理异步返回值的逻辑,可以设置异步处理的参数,如超时时间,以及在异步操作完成时如何处理结果。
目的:
AsyncHandlerMethodReturnValueHandler
允许开发者自定义异步方法返回值的处理方式,提供更大的灵活性。- 它可以用于处理长时间运行的任务,而不会阻塞服务器的线程,从而提高应用程序的响应性和并发处理能力。
- 使用
AsyncHandlerMethodReturnValueHandler
可以简化异步逻辑的处理,使控制器更专注于业务逻辑。
同步与异步区别。
HandlerMethodReturnValueHandler:
- 用途:用于处理同步方法的返回值。这是最常见的返回值处理器,用于处理标准的、同步的控制器方法返回值,如字符串、视图名、
ModelAndView
对象等。 - 业务场景:当你的控制器方法执行完毕并立即返回结果时,
HandlerMethodReturnValueHandler
负责将这些返回值转换成视图和模型数据,以便发送给客户端。
关键代码:
public interface HandlerMethodReturnValueHandler {
boolean supportsReturnType(MethodParameter returnType);
void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;
}
AsyncHandlerMethodReturnValueHandler:
- 用途:用于处理异步方法的返回值。它专门用于处理
DeferredResult
或Callable
类型的返回值,这些类型通常用于异步请求处理,允许延迟返回响应。 - 业务场景:当你的控制器方法需要执行长时间运行的操作,或者需要等待某些异步事件完成时,
AsyncHandlerMethodReturnValueHandler
负责管理这些异步操作的结果,并在完成后处理返回值。
关键代码:
public interface AsyncHandlerMethodReturnValueHandler extends HandlerMethodReturnValueHandler {
// 继承自 HandlerMethodReturnValueHandler 的方法
}
差异与业务作用:
- 同步与异步:
HandlerMethodReturnValueHandler
处理同步返回值,而AsyncHandlerMethodReturnValueHandler
处理异步返回值。 - 处理时机:
HandlerMethodReturnValueHandler
在方法调用后立即处理返回值,AsyncHandlerMethodReturnValueHandler
则需要等待异步操作完成。 - 超时处理:
AsyncHandlerMethodReturnValueHandler
可以设置超时时间,并在超时时采取特定行动,例如返回错误响应。 - 错误处理:
AsyncHandlerMethodReturnValueHandler
可以处理异步操作期间发生的异常,并决定如何响应这些异常。 - 应用场景:
HandlerMethodReturnValueHandler
适用于标准请求-响应模式,AsyncHandlerMethodReturnValueHandler
适用于需要异步处理的场景,如消息队列处理、文件上传/下载、长时间运行的任务等。
选择使用:
- 如果你的业务逻辑是同步的,使用
HandlerMethodReturnValueHandler
。 - 如果你的业务逻辑需要异步处理,例如响应不需要立即返回,或者需要在后台完成某些操作后再返回响应,使用
AsyncHandlerMethodReturnValueHandler
。
转载自:https://juejin.cn/post/7381333093548982310