Spring MVC 解读——@RequestMapping
2015-10-03 22:35
786 查看
Spring MVC 解读——@RequestMapping
为了降低文章篇幅,使得文章更目标化,简洁化,我们就不例举各种@RequestMapping的用法等内容了.文章主要说明以下问题:
Spring怎样处理@RequestMapping(怎样将请求路径映射到控制器类或方法)
Spring怎样将请求分派给正确的控制器类或方法
Spring如何实现灵活的控制器方法的
在Spring MVC 3.1 之前的版本中,Spring默认使用 DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter来处理 @RequestMapping注解和请求方法调用,而从3.1开始提供了一组新的API完成这些工作。相比之下,新的API更加的合理完善,开放,易拓 展,面向对象。这篇文章便是基于3.1的新API进行剖析的。
一、概念解析
在开始之前我们先了解下新的API中引入的新接口或者类,这会有助于后面的处理过程的理解。不得不说新的API提供了更多漂亮的抽象,你能感受到面向对象的魅力。RequestMappingInfo 这个类是对请求映射的一个抽象,它包含了请求路径,请求方法,请求头等信息。其实可以看做是@RequestMapping的一个对应类。
HandlerMethod 这个类封装了处理器实例(Controller Bean)和 处理方法实例(Method)以及方法参数数组(MethodParameter[])
MethodParameter 这个类从2.0就有了,它封装了方法某个参数的相关信息及行为,如该参数的索引,该参数所属方法实例或构造器实例,该参数的类型等。
HandlerMapping 该接口的实现类用来定义请求和处理器之前的映射关系,其中只定义了一个方法getHandler。
AbstractHandlerMethodMapping 这是HandlerMapping的一个基本实现类,该类定义了请求与HandlerMethod实例的映射关系。
RequestMappingInfoHandlerMapping 这个是AbstractHandlerMethodMapping的实现类,他维护了一个RequestMappingInfo和HandlerMethod的Map属性。
RequestMappingHandlerMapping 这个是RequestMappingInfoHandlerMapping的子类,它将@RequestMapping注解转化为RequestMappingInfo实例,并为父类使用。也就是我们处理@RequestMapping的终点。
InitializingBean 这个接口定义了其实现Bean在容器完成属性设置后可以执行自定义初始化操作,我们的AbstractHandlerMethodMapping便实现了这个接口,并且定义了一组自定义操作,就是用来检测处理我们的@RequestMapping注解。
概念讲的太多总不是什么好事。但明白了上述概念基本上就成功一半了,其中的实现相对@Autowired那篇简单多了。
二、InitialiZingBean.afterPropertySet()
我们从头开始,看看到底Spring是怎样检测并处理我们@RequestMapping注解的。不知大家还记不记的这段代码:?
上面概念中我们讲到InitiaizingBean接口,它的实现Bean会在容器完成属性注入后执行一个自定义操作,这不就满足initializeBean方法的执行唤醒嘛,我们来看它的实现:
?
?
RequestMappingHandlerMapping等Bean定义。而
RequestMappingHandlerMapping
实现了InitializingBean接口,因此,在初始化并装配该Bean实例时,执行到上述代码是,便会执行他的afterPropertySet方法。我们接下来看看他的afterPropertySet方法:
?
三、检测@RequestMapping
我们再看它是怎样判断是否是处理器的,以及怎么detect Handler Methods 的:?
?
下面我们看看细节:
?
?
PatternRequestCondition 它其实就是URL模式的封装,它包含了一个URL模式的Set集合。其实就是@RequestMapping注解中的value值得封装。
RequestMethodRequestCondition 它是@RequestMapping 注解中method属性的封装
ParamsRequestCondition 它是@RequestMapping注解中params属性的封装
等等,依次类推。因此RequestMappingInfo其实就是对@RquestMapping 的封装。
下面我们再看看怎样进行Combine的:
?
?
2)只有一个有时,使用这个。
3)两个都没有时,为空“”。
现在真正的url拼接是由PathMatcher来完成的了。我们就不看他的代码了就是一串if else的组合,重点是考虑进各种情况,我们来看下方法的注释吧:
清晰,全面吧,有兴趣的可以看一下代码,这里不讲了。
四、注册请求映射
上面我们已经讲了@RequestMapping的检测和处理,并且根据@RequestMapping生成了RequestMappingInfo实例,那Spring必定需要将这些信息保存起来,以处理我们的请求。第三节中我们提到一个方法还没有分析,就是registerHandlerMethod 方法:
?
五、承上启下
篇幅有些长了,超出字数限制了,只能分成两篇了..........................这章只分析了我们前面三个问题中的第一个,但是已经相当接近了。下一篇我们来讲,Spring怎样处理客户发来的请求,以及方法调用的。
相关文章推荐
- 为什么还是有很多人都选择NATIVE APP
- 捕获TextView超链接
- Android Fragment切换动画效果
- iOS 检测有没有安装其它应用 和ios9下要注意的地方
- LeetCodeOJ_202_Happy Number
- Android ListView多布局复用ArrayIndexOutOfBoundsException问题
- 网上看到的X度移动端笔试题
- ISMAR 2015 Poster - Remote Mixed Reality System Supporting Interactions with Virtualized Objects
- Android Studio新建Module时弹出窗口显示不全的问题
- 定制iOS 7中的导航栏和状态栏
- Android ActionBar相关
- android:图片圆角问题
- Cocos2D中的纹理大小计算
- Cocos2D中的纹理大小计算
- Cocos2D中的纹理大小计算
- Cocos2d-x 如何输出 Android用电话 腰带Tag的Log刊物
- 封装button
- ios软件开发 解决删除cell视图遮挡删除按钮的问题
- android 与 小米1S刷机学习
- iOS开发多线程篇—线程安全