HandlerMethodReturnValueHandler与适配器模式使用

57 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情

书接上文SpringBoot统一修改API返回值的两种方式中自定义HandlerMethodReturnValueHandler的内容,最后说道getDefaultReturnValueHandlers方法中添加了很多处理返回值的处理器,那这些处理器是如何生效的呢?

HandlerMethodReturnValueHandler在处理返回值时时如何使用适配器模式

通过分析DispatchServelet的doDispatch方法中的内容可以机进行追溯, 主要就行进行了各种适配器的选择

				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

可以看到HandlerAdapter中的具体实现类中与我们比较相关的还是AbstractHandlerMethodAdapter,但是进一步可以发现RequestMappingHandlerAdapter是继承自AbstractHandlerMethodAdapter且实现了相应功能 那最后是如何选择到我们的自定义HandlerMethodReturnValueHandler的内容的呢

DispatchServelet中获取到了HandlerAdapter 之后即开始执行hanle方法 通过追踪handle方法到RequestMappingHandlerAdapter#invokeHandlerMethod 继而追踪到

	@Override
	public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

		HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
		if (handler == null) {
			throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
		}
		handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
	}

最后通过适配器模式选择了排在第一个的我们的自定义的HandlerMethodReturnValueHandler的方法

选择适配器的方法即为通用的适配器模式实现方式,

	@Nullable
	private HandlerMethodReturnValueHandler selectHandler(@Nullable Object value, MethodParameter returnType) {
		boolean isAsyncValue = isAsyncReturnValue(value, returnType);
		for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
			if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) {
				continue;
			}
			if (handler.supportsReturnType(returnType)) {
				return handler;
			}
		}
		return null;
	}

通过将this.returnValueHandlers的第一个设置为自定义方法,即选中我们自定义的方法后就直接返回,不再进行后续方法的选择。