<mvc:annotation-driven>
在spring mvc 3.1增加了此标签的一些新的内置标签,个人能力有限,下面对这个标签进行简要的说明:
以下为可选配置:
<mvc:annotation-driven ignoreDefaultModelOnRedirect="true" conversion-service="" validator="" message-codes-resolver=""> <mvc:argument-resolvers> <bean class="com.lay.user.util.CustomerArgumentResolver"/> </mvc:argument-resolvers> <mvc:message-converters> <bean class=""/> </mvc:message-converters> <mvc:return-value-handlers> <bean class=""/> </mvc:return-value-handlers> </mvc:annotation-driven>
那么mvc:annotation-driven做了哪些事呢?
参考官方文档:
基本默认的就够用了,更高级用法可以自己指定。
public class CustomerArgumentResolver implements HandlerMethodArgumentResolver { public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { return null; } public boolean supportsParameter(MethodParameter parameter) { System.out.println(parameter.getParameterName() + " : " + parameter.getParameterName() + " \nParameterType: " + parameter.getParameterType() + " \nMethod: " + parameter.getMethod().getName()); return false; } }
代码说明: supportsParameter方法主要判别参数是否为该解析器所支持的,支持:true ,不支持:false
如果返回true的话则调用resolveArgument方法。
那么我们自定义的参数解析会在哪里调用呢?往下看:
我们查看HandlerMethodArgumentResolver的实现类:
没法插入图片。。。。。蛋疼
看代码:
/** * Resolves method parameters by delegating to a list of registered {@link HandlerMethodArgumentResolver}s. * Previously resolved method parameters are cached for faster lookups. * * @author Rossen Stoyanchev * @since 3.1 */ public class HandlerMethodArgumentResolverComposite implements 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 : 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; } }
解析参数的时候会自动找到HandlerMethodArgumentResolverComposite 这个 HandlerMethodArgumentResolver实现类,然后调用他的supportsParameter方法,supportsParameter方法会去判断是否支持该参数的解析,而我们自定义的参数解析器也被注入到for 循环中的argumentResolvers参数中了,不会上传图片,没法截图给大家看了,这里简单说下:
argumentResolvers是一个参数解析器集合,我们自定义的解析器会出现在这里,spring mvc默认把RequestParamMethodArgumentResolver 和 ServletModelAttributeMethodProcessor重复注册到最后,
spring mvc会一次找到supportsParameter方法返回true的解析器,并调用该方法的resolveArgument方法进行解析。
具体大家自己动手实现一下吧,不过多啰嗦了~!
通过实现HttpMessageConverter<T>接口便可以了,当然,你也可以继承AbstractHttpMessageConverter<T>,这样做会更轻松,具体做法参考源码
public interface HttpMessageConverter<T> { // Indicate whether the given class and media type can be read by this converter. boolean canRead(Class<?> clazz, MediaType mediaType); // Indicate whether the given class and media type can be written by this converter. boolean canWrite(Class<?> clazz, MediaType mediaType); // Return the list of MediaType objects supported by this converter. List<MediaType> getSupportedMediaTypes(); // Read an object of the given type from the given input message, and returns it. T read(Class<T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException; // Write an given object to the given output message. void write(T t, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException; }
文章的开头提到mvc:annotation-driven做了哪些事,其实使用mvc:annotation-driven默认情况下就注册了很多转换器了:
由此可以明白我前面的一片关于输出json格式的文章中提及的采用mvc:annotation-driven时只需加入jar包即可完成输出json的原因了,xml又何尝不能通过MarshallingHttpMessageConverter来解决呢?
最后,开发中可以使用mvc:annotation-driven 快速配置,在不注入自己的解析器的情况下基本默认注入的转换器差不多够用了,至于其他的
RequestMappingHandlerMapping
RequestMappingHandlerAdapter
可配置的属性以后在讨论。