首先来看下RequestMappingHandlerAdapter这个类的源码
/** * An {@link AbstractHandlerMethodAdapter} that supports {@link HandlerMethod}s * with the signature -- method argument and return types, defined in * {@code @RequestMapping}. * *Support for custom argument and return value types can be added via * {@link #setCustomArgumentResolvers} and {@link #setCustomReturnValueHandlers}. * Or alternatively to re-configure all argument and return value types use * {@link #setArgumentResolvers} and {@link #setReturnValueHandlers(List)}. * * @author Rossen Stoyanchev * @since 3.1 * @see HandlerMethodArgumentResolver * @see HandlerMethodReturnValueHandler */public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, InitializingBean { private List
customArgumentResolvers; private HandlerMethodArgumentResolverComposite argumentResolvers; private HandlerMethodArgumentResolverComposite initBinderArgumentResolvers; private List customReturnValueHandlers; private HandlerMethodReturnValueHandlerComposite returnValueHandlers; private List modelAndViewResolvers; private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager(); private List > messageConverters; private WebBindingInitializer webBindingInitializer; private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("MvcAsync"); private Long asyncRequestTimeout;............................................
从注释中可以了解到通过设置setCustomArgumentResolvers and setCustomReturnValueHandlers可以实现自定义出参和入参的相关规则
由于RequestMappingHandlerAdapter实现了InitializingBean接口所以在初始化的时候会调用afterPropertiesSet()方法
public void afterPropertiesSet() { if (this.argumentResolvers == null) { Listresolvers = getDefaultArgumentResolvers(); this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); } if (this.initBinderArgumentResolvers == null) { List resolvers = getDefaultInitBinderArgumentResolvers(); this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); } if (this.returnValueHandlers == null) { List handlers = getDefaultReturnValueHandlers(); this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers); } initControllerAdviceCache(); }
RequestMappingHandlerAdapter方法中有两个方法,getDefaultArgumentResolvers和getDefaultReturnValueHandlers方法,当然我们这边自定义是通过RequestMappingHandlerAdapter的customArgumentResolvers和customReturnValueHandlers属性来实现的,如果通过argumentResolvers和returnValueHandlers属性来直接设置的话,会将spring默认的请求入参和出参覆盖掉
getDefaultArgumentResolvers()方法可以看到我们自定义的入参处理类是被放在中后位置的,同样的getDefaultReturnValueHandlers()方法也是这样
/** * Return the list of return value handlers to use including built-in and * custom handlers provided via {@link #setReturnValueHandlers}. */ private ListgetDefaultReturnValueHandlers() { List handlers = new ArrayList (); // Single-purpose return value types handlers.add(new ModelAndViewMethodReturnValueHandler()); handlers.add(new ModelMethodProcessor()); handlers.add(new ViewMethodReturnValueHandler()); handlers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.contentNegotiationManager)); handlers.add(new CallableMethodReturnValueHandler()); handlers.add(new DeferredResultMethodReturnValueHandler()); handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory)); // Annotation-based return value types handlers.add(new ModelAttributeMethodProcessor(false)); handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.contentNegotiationManager)); // Multi-purpose return value types handlers.add(new ViewNameMethodReturnValueHandler()); handlers.add(new MapMethodProcessor()); // Custom return value types if (getCustomReturnValueHandlers() != null) { handlers.addAll(getCustomReturnValueHandlers()); } // Catch-all if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) { handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers())); } else { handlers.add(new ModelAttributeMethodProcessor(true)); } return handlers; }
此处需要注意的是返回值的处理,由于我们自定义的是处于偏后的位置,如果其他处理类已经返回了,那么我们这边是不会再进入我们自定义的处理类中的
我们可以看到HandlerMethodArgumentResolverComposite 类
public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver { ............................/** * Whether the given {@linkplain MethodParameter method parameter} is supported by any registered * {@link HandlerMethodArgumentResolver}. */ public boolean supportsParameter(MethodParameter parameter) { return getArgumentResolver(parameter) != null; } /** * Iterate over registered {@link HandlerMethodArgumentResolver}s and invoke the one that supports it. * @exception IllegalStateException if no suitable {@link HandlerMethodArgumentResolver} is found. */ public Object resolveArgument( MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter); Assert.notNull(resolver, "Unknown parameter type [" + parameter.getParameterType().getName() + "]"); return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); }......................................
实现了HandlerMethodArgumentResolver接口
而在其中
/** * Find a registered {@link HandlerMethodArgumentResolver} that supports the given method parameter. */ private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter); if (result == null) { for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) { if (logger.isTraceEnabled()) { logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" + parameter.getGenericParameterType() + "]"); } if (methodArgumentResolver.supportsParameter(parameter)) { result = methodArgumentResolver; this.argumentResolverCache.put(parameter, result); break; } } } return result; }
这里的argumentResolvers就是前文指定添加的
public void afterPropertiesSet() { if (this.argumentResolvers == null) { Listresolvers = getDefaultArgumentResolvers(); this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); } if (this.initBinderArgumentResolvers == null) { List resolvers = getDefaultInitBinderArgumentResolvers(); this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); } if (this.returnValueHandlers == null) { List handlers = getDefaultReturnValueHandlers(); /*********就是这里************/ this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers); /*********就是这里************/ } initControllerAdviceCache(); }