SpringMVC源码之Request是如何映射到正确的Controller
2017-02-13 11:12
344 查看
现在使用SpringMVC这个框架已经有一年多了,到现在还是只知道怎么写Dao,Service,Controller层,对于其实现原理还是一无所知,
所以还是想进一步提升自己对于框架的原理的理解。
本文旨在分析一个http请求如何映射到对应的Controller的,让读者明白框架到底做了哪些事情。
源码的版本是4.3.2.RELEASE。
因为RequestMappingHandleMapping是处理请求与HandlerMethod映射关系的一个核心类,
首先看下它的继承关系图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/58797c837fa50b1f935d44f9f20b9731.png)
首先看一下AbstractHandlerMethodMapping的initHandlerMethods方法中。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/9ee9c3c0a6eaa783ceca59cdfef90d81.png)
它首先找到Spring容器中初始化所有的Bean,然后isHandler方法是抽象方法,有其子类RequestMappingHandlerMapping去实现,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/074334b198027c5c0a36632a6bed9630.png)
可看到RequestMappingHandlerMapping的isHandler函数是查找是否有含有@Controller或RequestMapping注解的类。
接下来是detectHandlerMethods函数代码;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/4801807f7bf81a79cae7ac5f9d2c9712.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/0257bd2046284a6a21dad20a5590da29.png)
可以看出其中有个methods变量的Map类型,Key是Method,Value是RequestMappingInfo(如上图:RequestMappingInfoHandlerMapping继承AbstractHandlerMethodMapping实现,传入泛型
为RequestMappingInfo), 这里getMappingForMethod方法也是抽象方法,由RequestMappingHandlerMapping实现如下图所示,然后调用registerHandlerMethod方法.这个函数里是用
MappingRegistry(它是AbstractHandlerMethodMapping内部类),注册 HandlerMethod.
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/949eaf7116668b17b7858e435e61047c.png)
在这个函数中创建了方法的RequestMappingInfo,和类的RequestMappingInfo,并且合并到一起。
这个函数创建了RequestMappingInfo这个对象,找到含有@RqquestMapping的类和函数,并创建RequestMappingInfo对象。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/ee4ae3bd1f1980b0c9877f31c69a715b.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/9cf00add2ed50e941cc40eb51cc549e3.png)
可以看到RequestMappingInfo对象包含路径、方法、参数、请求头、名字、自定义类型等。builder方法后,创建RequestMappingInfo
对象。(这里用的是构造者模式)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/7bbc40165948911ade08366938ac761a.png)
可以看到,RequestMappingInfo类中包含PatternsRequestCondition,RequestMethodsRequestCondition、ParasRequestCondition、
HeadersRequestCondition等类,主要看一下url的patternsCondition的类的url匹配的类的获取匹配路径。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/49055e4ca8e0081c4f4b94d7746a6851.png)
可以看到首先匹配的是.,然后是带有通配符的.*。接着寻找匹配的路径。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/55a2ee24568a2060fb41c970ca90e6a9.png)
这个注册handlerMethod方法,是属于AbstractHandlerMethodMapping的一个内部类MappingRegistry,用来
专门维持所有的映射方法,并提供方法去查找方法去提供当前url映射的方法。这段代码主要是创建handlerMethod对象,
其中维护几个Map(键值对),用来存储映射的信息, 还有一个MappingRegistration专门保存注册信息的。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/6014ab478e1cb370e1619675f0f84c51.png)
结束:
本文只是对一个 http请求到正确匹配映射对应Controller层的方法的做了一些单简要的分析,虽然自己的水平有限,又很多地方
还是没有弄的很明白,文中难免有错误,也希望您指出来,欢迎有一起探讨学习SpringMVC的框架的同学。也包括探讨其他关于框架技术的。
所以还是想进一步提升自己对于框架的原理的理解。
本文旨在分析一个http请求如何映射到对应的Controller的,让读者明白框架到底做了哪些事情。
源码的版本是4.3.2.RELEASE。
因为RequestMappingHandleMapping是处理请求与HandlerMethod映射关系的一个核心类,
首先看下它的继承关系图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/58797c837fa50b1f935d44f9f20b9731.png)
首先看一下AbstractHandlerMethodMapping的initHandlerMethods方法中。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/9ee9c3c0a6eaa783ceca59cdfef90d81.png)
它首先找到Spring容器中初始化所有的Bean,然后isHandler方法是抽象方法,有其子类RequestMappingHandlerMapping去实现,
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/074334b198027c5c0a36632a6bed9630.png)
可看到RequestMappingHandlerMapping的isHandler函数是查找是否有含有@Controller或RequestMapping注解的类。
接下来是detectHandlerMethods函数代码;
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/4801807f7bf81a79cae7ac5f9d2c9712.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/0257bd2046284a6a21dad20a5590da29.png)
可以看出其中有个methods变量的Map类型,Key是Method,Value是RequestMappingInfo(如上图:RequestMappingInfoHandlerMapping继承AbstractHandlerMethodMapping实现,传入泛型
为RequestMappingInfo), 这里getMappingForMethod方法也是抽象方法,由RequestMappingHandlerMapping实现如下图所示,然后调用registerHandlerMethod方法.这个函数里是用
MappingRegistry(它是AbstractHandlerMethodMapping内部类),注册 HandlerMethod.
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/949eaf7116668b17b7858e435e61047c.png)
在这个函数中创建了方法的RequestMappingInfo,和类的RequestMappingInfo,并且合并到一起。
这个函数创建了RequestMappingInfo这个对象,找到含有@RqquestMapping的类和函数,并创建RequestMappingInfo对象。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/ee4ae3bd1f1980b0c9877f31c69a715b.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/9cf00add2ed50e941cc40eb51cc549e3.png)
可以看到RequestMappingInfo对象包含路径、方法、参数、请求头、名字、自定义类型等。builder方法后,创建RequestMappingInfo
对象。(这里用的是构造者模式)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/7bbc40165948911ade08366938ac761a.png)
可以看到,RequestMappingInfo类中包含PatternsRequestCondition,RequestMethodsRequestCondition、ParasRequestCondition、
HeadersRequestCondition等类,主要看一下url的patternsCondition的类的url匹配的类的获取匹配路径。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/49055e4ca8e0081c4f4b94d7746a6851.png)
可以看到首先匹配的是.,然后是带有通配符的.*。接着寻找匹配的路径。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/55a2ee24568a2060fb41c970ca90e6a9.png)
这个注册handlerMethod方法,是属于AbstractHandlerMethodMapping的一个内部类MappingRegistry,用来
专门维持所有的映射方法,并提供方法去查找方法去提供当前url映射的方法。这段代码主要是创建handlerMethod对象,
其中维护几个Map(键值对),用来存储映射的信息, 还有一个MappingRegistration专门保存注册信息的。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201702/6014ab478e1cb370e1619675f0f84c51.png)
结束:
本文只是对一个 http请求到正确匹配映射对应Controller层的方法的做了一些单简要的分析,虽然自己的水平有限,又很多地方
还是没有弄的很明白,文中难免有错误,也希望您指出来,欢迎有一起探讨学习SpringMVC的框架的同学。也包括探讨其他关于框架技术的。
相关文章推荐
- 详解SpringMVC请求的时候是如何找到正确的Controller[附带源码分析]
- springMVC原理(三):详解SpringMVC请求的时候是如何找到正确的Controller[附带源码分析]
- 详解SpringMVC请求的时候是如何找到正确的Controller[附带源码分析]
- 详解SpringMVC请求的时候是如何找到正确的Controller[附带源码分析]
- 详解SpringMVC请求的时候是如何找到正确的Controller
- 详解SpringMVC请求的时候是如何找到正确的Controller
- 详解SpringMVC请求的时候是如何找到正确的Controller
- 详解SpringMVC请求的时候是如何找到正确的Controller
- SpringMVC源码分析(二)之请求如何转发到对应的Controller
- SpringMVC请求的时候是如何找到正确的Controller
- SpringMVC常用注解實例詳解1:@Controller,@RequestMapping,@RequestParam,@PathVariable
- 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]
- 【springMVC 学习三】springmvc常用注解之@Controller和@RequestMapping
- SpringMVC常用注解實例詳解1:@Controller,@RequestMapping,@RequestParam,@PathVariable
- ASP.NET MVC:看 MVC 源码,学习:如何将 Area 中的 Controller 放到独立的程序集?
- SpringMVC常用注解實例詳解1:@Controller,@RequestMapping,@RequestParam,@PathVariable
- SpringMVC 基于注解的Controller @RequestMapping @RequestParam
- 以SpringMVC注解的形式 如何从Controller跳到另一个Controller 然后在转发到jsp页面
- SpringMVC 基于注解的Controller @RequestMapping @RequestParam..
- struts国际化默认保存在request中,一般通过过滤器修改让其保存在session;这介绍如何从<s:text>源码中修改local