spring mvc(4) HandlerMapping
在前面一节里提到,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的更多相关文章
- Spring MVC的handlermapping之SimpleUrlHandlerMapping初始化
前面信息同BeanNameUrlHandlerMapping,这里不再过多分析,详情请看 :Spring MVC的handlermapping之BeanNameUrlHandlerMapping初始化 ...
- spring mvc 自定义Handlermapping
上次大概写了个可以解决velocity 多视图的东西. 但是实际运用过程中又到处找了些资料看了下.这里 小计下: DispatcherServlet解析过程: ..1..HandlerMapping. ...
- Spring MVC的handlermapping之请求分发如何找到正确的Handler(BeanNameUrlHandlerMapping,SimpleUrlHandlerMapping)
本文讲的是Spring MVC如何找到正确的handler, 前面请求具体怎么进入到下面的方法,不再细说. 大概就是Spring mvc通过servlet拦截请求,实现doService方法,然后进入 ...
- Spring MVC 梳理 - handlerMapping和handlerAdapter分析
参考图片 综上所述我们来猜测一下spring mvc 中根据URL找到处理器Controller中相应方法的流程 ①:获取Request的URL ②:从UrlLookup这个map中找到相应的requ ...
- Spring MVC:HandlerMapping
HandlerMapping 的类图 Spring中存在两种类型的handlers.第一种是 handler mappings(处理程序映射).它们的角色定位与前面所描述的功能完全相同.它们尝试将当前 ...
- Spring MVC的handlermapping之BeanNameUrlHandlerMapping初始化
先介绍一下: BeanNameUrlHandlerMapping是基于配置文件的方式; 所有处理器需要在XML文件中,以Bean的形式配置. 缺点:配置繁琐; 如果多个URL对应同一个处理器,那么需要 ...
- Spring MVC的handlermapping之RequestMappingHandlerMapping初始化
RequestMappingHandlerMapping:这个handlerMapping是基于注解的同样,先上类图: 通过类图可以看到,同样是继承父类 AbstractHandlerMapping来 ...
- Spring MVC的handlermapping之请求分发如何找到正确的Handler(RequestMappingHandlerMapping)
这个思路同样是通过在AbstractHandlerMethodMapping里面来实现getHandlerInternal()实现自己的方法来处理寻找正确的处理器,不懂得请看上一篇. protecte ...
- spring mvc 关键接口 HandlerMapping HandlerAdapter
HandlerMapping Spring mvc 使用HandlerMapping来找到并保存url请求和处理函数间的mapping关系. 以DefaultAnnotationHandlerMa ...
随机推荐
- Flink的应用场景和架构
Flink的应用场景 Flink项目的理念就是:Flink是为分布式,高性能,随时可用以及准确的流处理应用程序打造的开源流处理框架.自2019年开源以来,迅速成为大数据实时计算领域炙手可热的技术框架. ...
- Shell编程—正则表达式
1什么是正则表达式 1.1定义 正则表达式是你所定义的模式模板,Linux工具可以用它来过滤文本.Linux 工具(比如sed编辑器或gawk程序)能够在处理数据时使用正则表达式对数据进行模式匹配. ...
- Java多线程_同步工具CyclicBarrier
CyclicBarrier概念:CyclicBarrier是多线程中的一个同步工具,它允许一组线程互相等待,直到到达某个公共屏障点.形象点儿说,CyclicBarrier就是一个屏障,要求这一组线程中 ...
- 最佳实践:Pulsar 为批流处理提供融合存储
非常荣幸有机会和大家分享一下 Apache Pulsar 怎样为批流处理提供融合的存储.希望今天的分享对做大数据处理的同学能有帮助和启发. 这次分享,主要分为四个部分: 介绍与其他消息系统相比, Ap ...
- Java-学习日记(100 == 100为true,1000 == 1000却为false?)
Integer底层设计 100 == 100为true,1000 == 1000却为false? 之前也写过String的==与equals的注意点,这次写下Integer的底层设计,不妨先运行下下面 ...
- Data Vault玩转数据仓库(三)
在Data Vault 2.0版本里,其不只是针对数据仓库的建模,同时也包含了架构,方法论以及实现.这篇挑几个概念,附上我个人对其的理解.同时也把这个系列的名字改成<Data Vault玩转数据 ...
- Unity 打AssetBundle和加载方案
一.如何组织assetBundle: unity5以前,打包需要自己去找依赖,然后需要按照拓扑图顺序压入AB栈,这样在最后打AB时才能有效利用依赖(栈内已有的AB才能作为依赖). unity5.x后, ...
- unity 4种实现动态障碍方法
此文将介绍4种实现动态障碍的方法,2种基于navmesh,2种基于astar算法. 1.基于navmesh. 1.制作场景障碍: a.有几个独立的障碍物,就定义几个user area,即,一个场景仅仅 ...
- selenium上手
功能自动化 前提 自动化的主要目的并不是为了找Bug,是为了证明功能可用 不只是所有的功能都可以自动化,如UI 并不是所有的项目都可以使用自动化,如selenium只能使用bs项目,小项目不适合使用自 ...
- 关于移动端的文本框获取焦点时导致fixed或absolute定位的按钮被手机键盘顶上去的问题
var win_h = $(window).height();//关键代码 window.addEventListener('resize', function () { if($(window).h ...