Spingmvc中的HandlerMapping负责解析请求URL,对应到Handler进行处理(这里的Handler一般为Controller里的一个方法method,也可以为servlet或者Controller等)
DispatcherServlet继承FrameworkServlet,FrameworkServlet继承HttpServletBean,HttpServletBean继承HttpServlet。
doService方法为servlet处理请求的入口,DispatcherServlet中做了方法覆盖,doService方法中的doDispatch(request,response)方法,是springmvc处理整个请求流程的关键。
mappedHandler =getHandler(processedRequest);
可以看出是从类变量this.handlerMappings中循环获取,当找到与之匹配的HandlerMapping时,返回类型为HandlerExecutionChain的handler。
从这里可以看出,在servlet初始化的时候,会对springmvc的HandlerMappings、HandlerAdapters等做初始化。
这里三个步骤,先对springmvc.xml里配置的HandlerMapping进行初始化、实例化,再对this.handlerMappings赋值,最后对this.handlerMappings进行排序。
这里涉及到两个HandlerMapping:
取:
可以看出,HandlerMapping初始化时,会将映射与handler存储到map里;处理请求时,从map里取出对应的处理handler。
先来看一个http请求的入口DispatcherServlet:
![](https://i-blog.csdnimg.cn/blog_migrate/2438a16fe77efc7af548daf7fb67d03e.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/e2d2c9bd5ff2a8ef7180f3bd31686f67.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/a2b1ce2aece9b97bd090a80ed5b2b46e.jpeg)
DispatcherServlet继承FrameworkServlet,FrameworkServlet继承HttpServletBean,HttpServletBean继承HttpServlet。
可以看出,springmvc的DispatcherServlet是在Servelt的基础上做了扩展处理。
![](https://i-blog.csdnimg.cn/blog_migrate/b5663a5ccbc265f1dd5dadc964629927.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/0123f2407145527c445bf0bd1d13eeb1.jpeg)
doService方法为servlet处理请求的入口,DispatcherServlet中做了方法覆盖,doService方法中的doDispatch(request,response)方法,是springmvc处理整个请求流程的关键。
![](https://i-blog.csdnimg.cn/blog_migrate/a53b4710fc4a172b78ac41e1ec80c516.jpeg)
mappedHandler =getHandler(processedRequest);
这行代码实现了为请求寻找处理handler,返回的是HandlerExecutionChain;
HandlerAdapter ha =getHandlerAdapter(mappedHandler.getHandler());
找到处理handler后,再去找匹配的HandlerAdapter,HandlerAdapter将完成后续处理。
继续看是如何找到请求对应的处理handler的:
![](https://i-blog.csdnimg.cn/blog_migrate/1483e5cdb11acab3593e4afa7f61fd1e.jpeg)
可以看出是从类变量this.handlerMappings中循环获取,当找到与之匹配的HandlerMapping时,返回类型为HandlerExecutionChain的handler。
这里this.handlerMappings中的值是从哪获取的呢?DispatcherServlet初始化的时候会给this.handlerMappings赋值:
![](https://i-blog.csdnimg.cn/blog_migrate/53f479007875be3471c88355b358bd87.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/68cf925992096a5f294904bddc32933d.jpeg)
从这里可以看出,在servlet初始化的时候,会对springmvc的HandlerMappings、HandlerAdapters等做初始化。
这里三个步骤,先对springmvc.xml里配置的HandlerMapping进行初始化、实例化,再对this.handlerMappings赋值,最后对this.handlerMappings进行排序。
这里的排序就是对HandlerMapping的order属性进行排序,这样,order属性值小的,就可以先对请求进行匹配。
从tomcat启动日志里可以看到HandlerMapping的初始化:
![](https://i-blog.csdnimg.cn/blog_migrate/eec993d9f52bfd5dadd4b0cea86ea9d8.jpeg)
这里涉及到两个HandlerMapping:
第一个是BeanNameUrlHandlerMapping,初始化时会将urlpath做映射存储;
第二个是RequestMappingHandlerMapping,初始化时会将Controller中配置@RequestMapping注解的方法做映射存储。
看源码:
存:
![](https://i-blog.csdnimg.cn/blog_migrate/b03ced8e0b4803bed7a2ce88ddde22ed.jpeg)
取:
![](https://i-blog.csdnimg.cn/blog_migrate/2eca0a96427a201310e7bc968e03294f.jpeg)
可以看出,HandlerMapping初始化时,会将映射与handler存储到map里;处理请求时,从map里取出对应的处理handler。
这就是HandlerMapping在springmvc里的大致处理流程,还有很多代码细节需要进一步研究。
接下来将会对HandlerAdapter进行分析