在前面一节里提到,DispatcherServlet在接收到请求后,通过HandlerMapping找到处理请求对应的Controller(其实处理请求器并不一定是Controller,还可以是HttpRequestHandler、Servlet)。下面我们来具体介绍一下spring中提供了那些HandlerMapping以及具体的实现原理。

  BeanNameUrlHandlerMapping,通过url和bean的名称进行匹配并且要求bean的名称以/开头。BeanNameUrlHandlerMapping在启动的时候会读取spring容器中所有以/开头的bean,建立映射关系。 

  例如在xml配置

<bean id="/home.htm" class="controller.IndexController"></bean>

  那么当访问/home.html时,会执行IndexController相应的方法。

  SimpleUrlHandlerMapping,配置url和bean的映射关系进行匹配。相对于BeanNameUrlHandlerMapping他将url和bean名称进行了解藕,但是需要配置以下映射关系,在启动时将映射关系注册到容器中。

<bean id="simpleUrlHandlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/index">indexController</prop>
</props>
</property>
</bean>

  spring mvc还提供了拦截器的功能,具体会在下面的章节讲到。所以针对特定的请求,我们还需要获取该请求对应的拦截器。事实上我们通过HandlerMapping接口返回的是一个HandlerExecutionChain。所以HandlerMapping在获取处理器的同时也会获取对应的拦截器(HandlerInterceptor),HandlerExecutionChain内部包含了该url对应的处理器和HandlerInterceptor。

 public interface HandlerMapping {
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}

  如果容器中存在多个HandlerMapping,那么会使用哪个HandlerMapping来处理请求呢?在DispatcherServlet进行初始化的时候,它会搜索容器中所有的HandlerMapping,并根据order属性进行排序。当接收到请求后,会循环所有的HandlerMapping,直到有一个HandlerMapping返回HandlerExecutionChain。如果容器中没有定义HandlerMapping怎么办?spring会读取DispatcherServlet.properties配置,默认配置BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping。

DispatcherServlet初始化HandlerMapping:

 private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
//根据orer排序
if (this.detectAllHandlerMappings) {
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<>(matchingBeans.values());
// We keep HandlerMappings in sorted order.
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
}
else {
//当detectAllHandlerMappings为false时,只使用名为handlerMapping的HandlerMapping
try {
HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerMapping later.
}
} // Ensure we have at least one HandlerMapping, by registering
// a default HandlerMapping if no other mappings are found.
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
if (logger.isDebugEnabled()) {
logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
}
}
}

spring mvc(4) HandlerMapping的更多相关文章

  1. Spring MVC的handlermapping之SimpleUrlHandlerMapping初始化

    前面信息同BeanNameUrlHandlerMapping,这里不再过多分析,详情请看 :Spring MVC的handlermapping之BeanNameUrlHandlerMapping初始化 ...

  2. spring mvc 自定义Handlermapping

    上次大概写了个可以解决velocity 多视图的东西. 但是实际运用过程中又到处找了些资料看了下.这里 小计下: DispatcherServlet解析过程: ..1..HandlerMapping. ...

  3. Spring MVC的handlermapping之请求分发如何找到正确的Handler(BeanNameUrlHandlerMapping,SimpleUrlHandlerMapping)

    本文讲的是Spring MVC如何找到正确的handler, 前面请求具体怎么进入到下面的方法,不再细说. 大概就是Spring mvc通过servlet拦截请求,实现doService方法,然后进入 ...

  4. Spring MVC 梳理 - handlerMapping和handlerAdapter分析

    参考图片 综上所述我们来猜测一下spring mvc 中根据URL找到处理器Controller中相应方法的流程 ①:获取Request的URL ②:从UrlLookup这个map中找到相应的requ ...

  5. Spring MVC:HandlerMapping

    HandlerMapping 的类图 Spring中存在两种类型的handlers.第一种是 handler mappings(处理程序映射).它们的角色定位与前面所描述的功能完全相同.它们尝试将当前 ...

  6. Spring MVC的handlermapping之BeanNameUrlHandlerMapping初始化

    先介绍一下: BeanNameUrlHandlerMapping是基于配置文件的方式; 所有处理器需要在XML文件中,以Bean的形式配置. 缺点:配置繁琐; 如果多个URL对应同一个处理器,那么需要 ...

  7. Spring MVC的handlermapping之RequestMappingHandlerMapping初始化

    RequestMappingHandlerMapping:这个handlerMapping是基于注解的同样,先上类图: 通过类图可以看到,同样是继承父类 AbstractHandlerMapping来 ...

  8. Spring MVC的handlermapping之请求分发如何找到正确的Handler(RequestMappingHandlerMapping)

    这个思路同样是通过在AbstractHandlerMethodMapping里面来实现getHandlerInternal()实现自己的方法来处理寻找正确的处理器,不懂得请看上一篇. protecte ...

  9. spring mvc 关键接口 HandlerMapping HandlerAdapter

    HandlerMapping Spring mvc 使用HandlerMapping来找到并保存url请求和处理函数间的mapping关系.   以DefaultAnnotationHandlerMa ...

随机推荐

  1. Flink的应用场景和架构

    Flink的应用场景 Flink项目的理念就是:Flink是为分布式,高性能,随时可用以及准确的流处理应用程序打造的开源流处理框架.自2019年开源以来,迅速成为大数据实时计算领域炙手可热的技术框架. ...

  2. Shell编程—正则表达式

    1什么是正则表达式 1.1定义 正则表达式是你所定义的模式模板,Linux工具可以用它来过滤文本.Linux 工具(比如sed编辑器或gawk程序)能够在处理数据时使用正则表达式对数据进行模式匹配. ...

  3. Java多线程_同步工具CyclicBarrier

    CyclicBarrier概念:CyclicBarrier是多线程中的一个同步工具,它允许一组线程互相等待,直到到达某个公共屏障点.形象点儿说,CyclicBarrier就是一个屏障,要求这一组线程中 ...

  4. 最佳实践:Pulsar 为批流处理提供融合存储

    非常荣幸有机会和大家分享一下 Apache Pulsar 怎样为批流处理提供融合的存储.希望今天的分享对做大数据处理的同学能有帮助和启发. 这次分享,主要分为四个部分: 介绍与其他消息系统相比, Ap ...

  5. Java-学习日记(100 == 100为true,1000 == 1000却为false?)

    Integer底层设计 100 == 100为true,1000 == 1000却为false? 之前也写过String的==与equals的注意点,这次写下Integer的底层设计,不妨先运行下下面 ...

  6. Data Vault玩转数据仓库(三)

    在Data Vault 2.0版本里,其不只是针对数据仓库的建模,同时也包含了架构,方法论以及实现.这篇挑几个概念,附上我个人对其的理解.同时也把这个系列的名字改成<Data Vault玩转数据 ...

  7. Unity 打AssetBundle和加载方案

    一.如何组织assetBundle: unity5以前,打包需要自己去找依赖,然后需要按照拓扑图顺序压入AB栈,这样在最后打AB时才能有效利用依赖(栈内已有的AB才能作为依赖). unity5.x后, ...

  8. unity 4种实现动态障碍方法

    此文将介绍4种实现动态障碍的方法,2种基于navmesh,2种基于astar算法. 1.基于navmesh. 1.制作场景障碍: a.有几个独立的障碍物,就定义几个user area,即,一个场景仅仅 ...

  9. selenium上手

    功能自动化 前提 自动化的主要目的并不是为了找Bug,是为了证明功能可用 不只是所有的功能都可以自动化,如UI 并不是所有的项目都可以使用自动化,如selenium只能使用bs项目,小项目不适合使用自 ...

  10. 关于移动端的文本框获取焦点时导致fixed或absolute定位的按钮被手机键盘顶上去的问题

    var win_h = $(window).height();//关键代码 window.addEventListener('resize', function () { if($(window).h ...