在前面的文章中有说明:<mvc:annotation-driven />
在spring 3.1
之后会注册了RequestMappingHandlerMapping
和RequestMappingHandlerAdapter
,本文详细介绍具体的实现。
在xml
文件中配置mvc:annotation-driven
,有一个专门的类BeanDefinitionParser
来解析处理这个东西。 它只有一个方法:
|
|
用来专门处理<beans></beans>
里面的配置元素。然后找到这样的一个实现类AnnotationDrivenBeanDefinitionParser
|
|
解析过程的代码如下:
|
|
默认注册组件MvcNamespaceUtils.registerDefaultComponents
的如下:
|
|
至此所注册的HandlerMapping
和HandlerAdapter
都找到了。
|
|
开启了<mvc:annotation-driven/>
,同时注册了两个bean。有RequestMappingHandlerMapping
和RequestMappingHandlerAdapter
作为支持,这里简单说明下:RequestMappingHandlerMapping
它会判断一个bean是否含有@Controller
标签或者@RequestMapping
,如果有其一则会将该bean纳入作为它的处理对象,之后会进一步处理该类上含有@RequestMapping
注解的方法。这样做主要是由于@RequestMapping
可以配置在类上(作为基础地址),也可以配置在方法上,我们有时候会在类上配置@RequestMapping
,有时候又不会,所以只要类注解含有@Controller
或者含有@RequestMapping
,RequestMappingHandlerMapping
都会将他们纳入自己的handler管辖范围。所以仅仅在方法中含有@RequestMapping
注解是不被处理的,必须在类上加入@RequestMapping
或者@Controller
,所以@Controller
又不是必须的。
|
|
@Controller
使得StringAction
这个handler纳入RequestMappingHandlerMapping
管理,RequestMappingHandlerMapping
会将这个handler和handler中的每一个含有@RequestMapping
的方法都会构建成一个HandlerMethod
对象,该类的构造函数为HandlerMethod(Object bean, Method method)
,经过这样的包装之后将构造的HandlerMethod
对象作为新的handler,然后进行选择适配器,进行方法调用,当RequestMappingHandlerAdapter
判断是否support一个类时,就是依据当前的handle是否是HandlerMethod
类型。若是则由RequestMappingHandlerAdapter
来调度执行该handler(handler为HandlerMethod
类型)的中的method方法。以上就是整个大体的流程。
- 第一步要弄清
RequestMappingHandlerMapping
在初始化时是如何寻找它所管辖的bean。
RequestMappingHandlerMapping
的父类AbstractHandlerMethodMapping
在初始化时,会调用这样的一个方法initHandlerMethods
,在该方法中,遍历所有的bean然后判断他们是不是含有@Controller
或者@RequestMapping
注解:
|
|
其中的isHandler
(由子类RequestMappingHandlerMapping
实现)的判断方法代码如下:
|
|
如果handler含有了上述注解的其中之一,就会进一步处理该handler的方法中含有@RequestMapping
的方法:
|
|
遍历这个handler类的所有方法,过滤条件就是这个内部类MethodFilter
,其中的getMappingForMethod
方法:
|
|
如找到了含有RequestMapping
注释的方法,则由这个注释的内容构建一个RequestMappingInfo
对象:
|
|
就是拿RequestMapping
注释的内容进一步封装进RequestMappingInfo
对象中。对handler的所有方法过滤完成之后,就要遍历这些方法,以一定的方式存储起来。
|
|
这里的this.handlerMethods
就包含了所有管辖的bean,key为RequestMappingInfo
对象,value为handler和它中含有@RequestMapping
注释的方法method构建的HandlerMethod。
|
|
至此,RequestMappingHandlerMapping
的初始化注册工作就完成了。
请求http://localhost:8080/string?name=a`,RequestMappingHandlerMapping`会匹配到由`StringAction`对象和它的包含注释的方法`testMessageConverter`构建的`HandlerMethod`对象,该对象将作为handler,然后再遍历`HandlerAdapter`判断它们是否支持这个handler,`RequestMappingHandlerAdapter`的判断依据为是否是`HandlerMethod` 类型(在AbstractHandlerMethodAdapter
类中):
|
|
然后将得到匹配,有了这个HandlerMethod
对象,便可以通过RequestMappingHandlerAdapter
来调度执行HandlerMethod
其中的方法。
|
|
mappedHandler
包含handle(这里是HandlerMethod
)和一些HandlerInterceptor
.
|
|