springmvc中RequestMapping的解析
1
在研究源码的时候,我们应该从最高层来看,所以我们先看这个接口的定义:
/**
1.定义一个将请求和处理器进行映射的接口,而这个接口主要的作用就是进行路由,将url映射到HandlerExecutionChain。
开发人员也可以自己实现这个接口,虽然这是不必须的,因为现在的springmvc中已经提供了大量的实现,最典型的就是
BeanNameUrlHandlerMapping,SimpleUrlHandlerMapping,RequestMappingHandlerMapping等等,以前的版本中,如果我们没有显式的设置的话
那么就是系统使用的就是前面两个RequestMapping,但是较行的版本使用的是BeanNameUrlHandlerMapping,DefaultAnnotationHandlerMapping这两个-配置了mvc:annotation-driven注解的话 就是
RequestMappingHandlerMapping
)
2.在映射的结果中可以包括0或多个的拦截器,在执行处理器的前面会先执行preHandle,如果拦截器都返回true的时候,才会执行处理器的逻辑
同时处理参数的能力也是非常的强大的,我们可以定义RequestMapping处理各种参数(但是明显不用这样做的,我们可以直接定义参数转化器) 3.因为系统可以设置多个的HandlerMapping,所以我们应该实现Ordered这个接口,表示个各自的优先级,越小优先级越高。默认是Integer.MAX_VALUE.优先级是最低的
*/
public interface HandlerMapping { //这个属性表示的是url对应的HandlerMapping
String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping"; //这个request匹配度最高的HanlderMapping
String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern"; //是否支持类级别的映射 像我们的DefaultAnnotationHandlerMapping就使用了这个属性来表示支持类级别的。(如果我们没有设置的话,默认就是支持的
//@see AnnotationMethodHandlerAdapter$ServletHandlerMethodResolver.useTypeLevelMapping())
String INTROSPECT_TYPE_LEVEL_MAPPING = HandlerMapping.class.getName() + ".introspectTypeLevelMapping"; //也是request中的KEY名称,值时map,存放在的是键值对
String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables"; //和上面差不多,但是类别有一些不同 存放的是Matrix Variable(就是值可以用;分割的那个)
String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".matrixVariables"; //HandlerMapping支持的媒体类型
String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes"; /**
这个这个类的唯一一个方法,根据职责单一原则,我们就明白了,HandlerMapping的唯一职责就是将一个请求根据不同的策略
最终转化为HandlerExecutionChain这样的一个对象,这里不是一个接口,而是一个类,这个类就是封装了处理器和一系列的
拦截器,并且代理了这一系列处理的的前置和后置处理
*/
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception; }
通过上面的分析已经大概明白了HandlerMapping的目的,他的目的就是一个请求来了以后,我们需要通过HandlerMapping来构造一个执行后续操作的环境,这里面包括我们定义的支持媒体类型,随请求来的各种参数,系统中设置的拦截器等等。如果要我说,这一步相当于springmvc的入口吧。
我们再看一个接口实现的基础的抽象类,这个类就是就是提供了一些基本的设施,留下一个主要的工作给子类来进行实现,这是个是AbstractHandlerMapping。因为这个很多的方法,我并不会将类贴出来,主要分析一下这个类实现了哪些的功能,以及我们关注点在哪里,扩展在哪里。
这个抽象类不仅实现了HandlerMapping,而且实现了Ordered接口,这个接口在HandlerMapping中提示了我们就是定义自己的顺序。并且继承了spring的基础设置类,来提供一些ServletContext和WebApplicationContext这些的引用。所以,如果我们要实现自己的HandlerMapping的话,还是建议这个抽象类就OK了。
我们看最主要的一个方法:
@Override
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
return getHandlerExecutionChain(handler, request);
}
这里有主要的两个部分,第一部分就是:getHandlerInternal(...)是一个模板方法,让子类来返回处理器,处理器就是我们定义的controller,第二部分就是getHandlerExecutionChain方法,这个方法返回的就是 HandlerExecutionChain,这也在前面讲过,就是将某个url映射到其中去,而HandlerExecutionChain其中封装了很多的东西,这其中包括我们调用getHandlerInternal返回的处理器,包括这个针对于这个url的拦截器链。
//add time : 17.05.15
经过了上面两个主要的类之后,到了真正处理处理器逻辑的时候了,这个类就是HandlerAdapter,主要的作用就是针对于处理器进行逻辑操作-> 数据的反序列化,参数的解析,返回数据的反序列化,视图的解析等等。这个接口采用了适配器设计模式,接口主要提供了三个方法:
public interface HandlerAdapter {
// 判断此适配器是否支持此处理器
boolean supports(Object handler);
// 根据请求和处理器处理真正的逻辑,这里面是会调用我们的业务逻辑的 这其中是最为复杂的,
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
// 获取last-modifier 时间
long getLastModified(HttpServletRequest request, Object handler);
}
springmvc中RequestMapping的解析的更多相关文章
- 在springmvc中 @RequestMapping(value={"", "/"})是什么意思
这个意思是说请求路径 可以为空或者/ 我给你举个例子:比如百度知道的个人中心 访问路径是 http://zhidao.baidu.com/ihome,当然你也可以通过 http://zhidao.ba ...
- SSM-SpringMVC-23:SpringMVC中初探异常解析器
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客要讲的是异常解析器,SimpleMappingExceptionResolver简单映射异常解析器 可 ...
- SpringMVC中 -- @RequestMapping的作用及用法
一.@RequestMapping 简介 在Spring MVC 中使用 @RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.x ...
- SSM-SpringMVC-13:SpringMVC中XmlViewResolver视图解析器
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 还记得上篇博客提出来的问题吗? BeanNameViewResolver视图解析器每使用一道视图,就得手工配 ...
- springmvc 中RequestMapping注解的使用
1.RequestMapping注解既可以修饰方法,又可以修饰类型,类型指定的url相对于web跟路径,而方法修饰的url相对于类url: 2.RequestMapping的几个属性: value:用 ...
- Springmvc中@RequestMapping 属性用法归纳
简介: @RequestMapping RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. RequestM ...
- SpringMVC注解@RequestMapping全面解析---打酱油的日子
@RequestMapping 可以出现在类级别上,也可以出现在方法上.如果出现在类级别上,那请求的 url 为 类级别上的@RequestMapping + 方法级别上的 @RequestMappi ...
- springmvc中的页面解析器ViewResolver不起作用,变量输出字符串的解决方案
<web-app xmlns:web="http://xmlns.jcp.org/xml/ns/javaee"> <servlet> <servlet ...
- springmvc中@RequestMapping的使用
通过RequestMapping注解可以定义不同的处理器映射规则. 1.1 URL路径映射 @RequestMapping(value="/item")或@RequestMappi ...
随机推荐
- Objective-C实现发短信和接电话
发短信: [[UIApplication sharedApplication]openURL:[NSURL URLWithString:@"sms://10000"]]; 打电话: ...
- 知方可补不足~Sqlserver中的几把锁和.net中的事务级别
回到目录 当数据表被事务锁定后,我们再进行select查询时,需要为with(锁选项)来查询信息,如果不加,select将会被阻塞,直到锁被释放,下面介绍几种SQL的锁选项 SQL的几把锁 NOLOC ...
- [C#反射]C#中的反射解析及使用.
1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 参考: C#反射,MSDN编程指南 反射是一个程序集发现及运行的过程,通过 ...
- mysql 的简单优化
合理的建立索引的建议: (1) 越小的数据类型通常更好:越小的数据类型通常在磁盘.内存和CPU缓存中都需要更少的空间,处理起来更快. (2) 简单的数据类型更好:整型数据比起字符,处理开销更小,因 ...
- rabbitmq消息队列——"Hello World!"
RabbitMQ 一."Hello World!" 1.简介: RabbitMQ是一种消息中间件,主要思想很简单:接收消息并转发.你可以将它设想为一个邮局:你往里面发送邮件并确保邮 ...
- Change Git Default Editor in Windows
On 32 bit Win OS: git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' - ...
- Create New Commands in Tcl
Create New Commands in Tcl eryar@163.com 摘要Abstract:Tcl/Tk脚本可以很容易实现用户自定义的命令,方便的创建图形化的用户界面GUI,所以Tcl和T ...
- 冒泡排序java代码
冒泡排序就是依次取出最大数,然后依次交换放到数组最后边. 直观写法: public long[] sort(long[] a){ int n = a.length - 1; // Step:1 选出最 ...
- hibernate(十)双向关联关系的CRUD
本文链接:http://www.orlion.ml/28/ 一.保存 1. 假设一个group有多个user,一个user只属于一个group,当保存user对象到数据库中时可以 User u = n ...
- haslayout详解
定义 haslayout是IE7-浏览器的特有属性.hasLayout是一种只读属性,有两种状态:true或false.当其为true时,代表该元素有自己的布局,否则代表该元素的布局继承于父元素. [ ...