关键的接口
HandlerMethodArgumentResolver(处理器方法参数解析器)
它的实现类如下:
常用的有:
- ServletRequestMethodArgumentResolver和ServletResponseMethodArgumentResolver处理了自动绑定HttpServletRequest和HttpServletResponse
- RequestParamMapMethodArgumentResolver处理了@RequestParam
- RequestHeaderMapMethodArgumentResolver处理了@RequestHeader
- PathVariableMapMethodArgumentResolver处理了@PathVariable
- ModelAttributeMethodProcessor处理了@ModelAttribute
- RequestResponseBodyMethodProcessor处理了@RequestBody
它的调用过程源码
springmvc工作流程源码参考:https://blog.csdn.net/sumengnan/article/details/105381225
1、直接就开始获取RequestMappingHandlerAdapter适配器类,之后调用handle方法去执行我们的handler:
2、通过AbstractHandlerMethodAdapter类,把handler强转成HandlerMethod类,然后调用子类RequestMappingHandlerAdapter:
3、继续调用invokeHandlerMethod
由于下面要用到RequestMappingHandlerAdapter的argumentResolvers属性,这里先说一下:
RequestMappingHandlerAdapter类实现了InitializingBean接口,了解过bean生命周期都知道,在bean实例化时会执行afterPropertiesSet方法,如图:
执行getDefaultArgumentResolvers方法,初始化下面的方法参数解析器,还有初始化绑定解析器和返回值处理器就不说了:
之后创建HandlerMethodArgumentResolverComposite对象并把这些解析器add进去。
4、在这里把HandlerMethod经过createInvocableHandlerMethod方法转成了ServletInvocableHandlerMethod类。
解释:
实际ServletInvocableHandlerMethod本就是HandlerMethod的子类,如图:
HandlerMethodArgumentResolverComposite是对所有HandlerMethodArgumentResolver实现类的调用的一个中间人。
就是HandlerMethodArgumentResolver实现类都是由它调用的。类似于代理模式
5、进入invokeAndHandle
6、在这个invokeForRequest方法中,就真正的获取方法参数值,然后通过doInvoke方法调用handler了
7、现在主要关注参数的问题,所以进入getMethodArgumentValues方法,开始解析参数。
按照参数的顺序for循环一个一个解析。
8、由于上面第三步时,已经实例化好了HandlerMethodArgumentResolverComposite对象,所以会调用此对象的supportsParameter和resolveArgument方法。
再由HandlerMethodArgumentResolverComposite调用对应的解析器类。通过解析器的supportsParameter方法判断此解析器是否可用
9、举个例子:例如当前hander的参数使用了@RequestParam注解。则经过supportsParameter方法判断此实现类可用于解析此参数。
便会执行resolveArgument方法进行处理。
10、完毕
有什么作用?
我们可以自定义注解,来解析参数。
例如:自定义@LoginUser注解,来直接在参数上获取当前登录的用户,是不是方便多了!
参考:https://blog.csdn.net/sumengnan/article/details/102852658