《SpringMVC从入门到放肆》四、SpringMVC配置式开发(处理器映射器)
上一篇我们讲解了DispatcherServlet的url-pattern配置详解,今天我们来真正对SpringMVC进行配置式开发。
所谓配置式开发是指“处理器类是程序员自己定义的、实现了特定接口的类,然后在SpringMVC配置文件中对该类进行显式的,明确的注册”的开发方式。今天我们的开发还是将中央调度器的url-pattern配置成*.do。然后将springmvc.xml的静态资源访问先取消。
一、处理器映射器(BeanNameUrlHandlerMapping)
handlerMapping接口负责根据request请求找到对应的Handler处理器及Interceptor拦截器,并将它们封装在HandlerExecutionChain对象中,返回给中央调度器。其常用的实现类有两种:
1、BeanNameUrlHandlerMapping
2、SimpleUrlHandlerMapping
这里着重说明SimpleUrlHandlerMapping。BeanNameUrlHandlerMapping我们简单来看一下源码:
public class BeanNameUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping { /**
* Checks name and aliases of the given bean for URLs, starting with "/".
*/
@Override
protected String[] determineUrlsForHandler(String beanName) {
List<String> urls = new ArrayList<String>();
if (beanName.startsWith("/")) {
urls.add(beanName);
}
String[] aliases = getApplicationContext().getAliases(beanName);
for (String alias : aliases) {
if (alias.startsWith("/")) {
urls.add(alias);
}
}
return StringUtils.toStringArray(urls);
} }
上方BeanNameUrlHandlerMapping类中只有一个方法determineUrlsForHandler()。该方法中把所有以斜杠开头的请求的BeanName都放到了一个名叫urls的List中。然后返回给了中央调度器。但是有一个弊端,比如我有两个请求都由一个Controller来处理,这时我们的springmvc.xml文件的配置方式如下:
<!-- 注册SpringMVC处理器 -->
<bean id="/my.do" class="cn.wechatbao.controller.MyController"></bean>
<bean id="/you.do" class="cn.wechatbao.controller.MyController"></bean>
这样Spring容器在创建MyController实例的时候,一次性创建了两个,而对于我们来说,其实一个实例就可以对两个或多个请求进行处理。所以我们继续来讲解SimpleUrlHandlerMapping方法。
二、处理器映射器(SimpleUrlHandlerMapping)
要使用SimpleUrlHandlerMapping我们需要将其注册到SpringMVC中,如图,我们在默认的处理器映射器中并没有发现该实现类。所以需要注册。
注册方式:(springmvc.xml如下)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 注册视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/my.do">myController</prop>
<prop key="/you.do">myController</prop>
<prop key="/he.do">myController</prop>
</props>
</property>
<!--
这种方式也可以实现多个请求交由一个Controller处理的需求
<property name="urlMap">
<map>
<entry key="/my.do" value="myController"></entry>
<entry key="/you.do" value="myController"></entry>
<entry key="/he.do" value="myController"></entry>
</map>
</property>
-->
</bean> <!-- 注册SpringMVC处理器 -->
<bean id="myController" class="cn.wechatbao.controller.MyController"></bean>
</beans>
注意:该种配置方式只针对多个请求用一个Controller处理才使用。
三、处理器映射器源码分析
1、当客户端发送请求到达中央调度器(DispatcherServlet)时,DispatcherServlet首先进入到doService方法在doService()方法里,对request设计一些属性,然后又进入到了doDispatch()方法,在doDispatch()方法里,我们着重来看以下代码:
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
2、从doDispatch()方法又进入了一个getHandler()的方法,如下
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
在该方法中,使用了一个forEach循环,来循环所有的处理器映射器,根据每个处理器映射器(HandlerMapping)来获取与之对应的处理器执行链(HandlerExecutionChain)。
进入hm.getHandler(request);方法来看。
3、继续hm.getHandler(request);方法
@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);
} HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
4、接下来又走到了HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);这个方法。我们就不继续深究了。有兴趣的朋友可以自己再研究下去。我们得出的结论是经过了一系列的方法,最终返回给中央调度器一个HandlerExecutionChain对象。明白这个我们的目的就已经达到了。
《SpringMVC从入门到放肆》四、SpringMVC配置式开发(处理器映射器)的更多相关文章
- 4.SpringMVC 配置式开发-处理器映射器
处理器映射器 HandlerMapping HandlerMapping 接口负责根据request请求找到对应的Handler处理器及Interceptor拦截器, 并将它们封装在HandlerEx ...
- 6.SpringMVC 配置式开发-处理器
处理器除了实现Controller 接口外,还可以继承自一些其他的类,来完成一些特殊的功能 1.继承自AbstractController类 若处理器继承自AbstractController类,那么 ...
- 5.SpringMVC 配置式开发-处理器适配器
处理器适配器HandlerAdapter 1.SimpleControllerHandlerAdapter(默认) 所有实现了 Controller 接口的处理器 Bean,均是通过SimpleCon ...
- SpringMVC的HandlerMapping(处理器映射器)
SpringMvc有四种HandlerMapping:BeanNameUrlHandlerMapping ,SimpleUrlHandlerMapping,ControllerClassNameHan ...
- 【SpringMVC笔记】第三课 处理器映射器+处理器适配器
第二课的例子中,在springmvc.xml中配置使用了第一种处理器映射器和处理器适配器,如下所示. <!-- 配置第一种处理器映射器 BeanNameUrlHandlerMapping --& ...
- springMVC三种处理器映射器
1.配置处理器映射器,springmvc默认的处理器映射器BeanNameUrlHandlerMapping <bean class="org.springframework.web. ...
- 《SpringMVC从入门到放肆》八、SpringMVC注解式开发(基本配置)
上一篇我们结束了配置式开发,配置式开发目前在企业中用的并不是很多,大部分企业都在使用注解式开发,所以今天我们就来学习注解式开发.所谓SpringMVC注解式开发是指,处理器是基于注解的类的开发方式.对 ...
- 《SpringMVC从入门到放肆》二、SpringMVC的执行流程及默认配置
上一篇博文我们做了一个hello world的程序,并且已经成功的跑起来了.这一篇我们来深入的了解一下SpringMVC的执行流程以及一些其它的配置. 一.执行流程 来解释一下上图中的各个名词1.Di ...
- 《SpringMVC从入门到放肆》三、DispatcherServlet的url-pattern配置详解
上一篇我们详细解释了一下SrpingMVC的执行流程以及一些默认的配置,在Spring的思想中,就是默认大于配置.今天我们来详细的研究一下DispatcherServlet的url-pattern配置 ...
随机推荐
- mac上虚拟机安装旧版本的macosx 10.8
前言 由于测试的需要,需要10.8的macosx,但又不想降级自己mac版本,所以还是装虚拟机,Parallels Desktop试验了安装不了osx,就换VMware Fusion,发现是可以的. ...
- springboot学习(三)————使用HttpMessageConverter进行http序列化和反序列化
以下内容,如有问题,烦请指出,谢谢! 对象的序列化/反序列化大家应该都比较熟悉:序列化就是将object转化为可以传输的二进制,反序列化就是将二进制转化为程序内部的对象.序列化/反序列化主要体现在程序 ...
- 关于PLC
学电气的一方面是单片机,一方面是PLC,,,,常常看到说选择比努力更重要,,单片机都很熟悉了,我就来介绍一下PLC..... 然后呢我先吹吹牛,,,目的是让大家相信我介绍的PLC绝对是亲身体验.... ...
- php按照中文首字母排序
1> 网络上很多php的工具类可以将汉字转为拼音: 2> 将拼音进行排序即可 另一种则是类似mysql转码方式: 1 foreach ($array as $key=>$value) ...
- cd 命令详解
cd 命令 作用: cd 用来切换目录,目录表示法可为绝对路径或相对路径, 若目录名称省略,则变换至使用者的登陆目录. ~ 可表示为家目录,.为当前目录,..为上级目录 语法: cd (选项)(参数 ...
- 如何使用vuex
一.何为vuex? vuex其实是一种状态管理模式,那么什么是状态管理模式呢?简单的理解就是把一些状态或者数据集中到一个地方管理,然后所有的组件共享这些数据,当数据改变时,用到这些数据的组件也会相应的 ...
- 【自问自答】关于 Swift 的几个疑问
感觉自己给自己释疑,也是一个极为有趣的过程.这次,我还新增了"猜想"一栏,来尝试回答一些暂时没有足够资料支撑的问题. Swift 版本是:4.0.3.不同版本的 Swift,可能无 ...
- 鸟哥的linux私房菜学习-(二)VMware虚拟机及linux系统安装过程
一.安装虚拟机 1.虚拟机常用版本及注册码地址:https://pan.baidu.com/s/1dFnkBrN#list/path=%2FSoftware%20Big%2FVMware%20Work ...
- Intellij idea破解办法
最开始的时候intellij用得是社区版,专业版是要钱的.但是社区版的功能确实弱了很多:比如Diagrams功能就没有,比如社区版不支持web项目,想起个tomcat跑个web项目都没法搞.于是,重新 ...
- egrep及扩展正则表达式 与正则表达式不同处
egrep及扩展正则表达式与正则表达式不同处 正则表达式有两类,分为基本正则表达式和扩展正则表达式,是使用命令egrep来使用扩展正则表达式,它与grep很多功能相同,仅在元字符上实现了些扩展扩展,在 ...