承接前文SpringMVC源码情操陶冶-AbstractHandlerMapping,前文主要讲解了如何获取handler处理对象,本文将针对beanName注册为handler对象作下解析

AbstractUrlHandlerMapping#registerHandler()-注册handler对象

内部含有两个此方法的重载,分别作简单的介绍

AbstractUrlHandlerMapping#registerHandler(String[] urlPaths, String beanName)-多路径绑定一个bean

多个路径绑定同一个bean,源码奉上

	protected void registerHandler(String[] urlPaths, String beanName) throws BeansException, IllegalStateException {
Assert.notNull(urlPaths, "URL path array must not be null");
//最终调用另外一个重载方法
for (String urlPath : urlPaths) {
registerHandler(urlPath, beanName);
}
}

AbstractUrlHandlerMapping#registerHandler(String urlPath,Object handler)-请求路径绑定bean

注意此处的urlPath参数可以为ant-style模式的值,源码奉上

	protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
//两参数不可为空
Assert.notNull(urlPath, "URL path must not be null");
Assert.notNull(handler, "Handler object must not be null");
Object resolvedHandler = handler; // Eagerly resolve handler if referencing singleton via name.
if (!this.lazyInitHandlers && handler instanceof String) {
String handlerName = (String) handler;
if (getApplicationContext().isSingleton(handlerName)) {
resolvedHandler = getApplicationContext().getBean(handlerName);
}
} //是否已存在对应的handler
Object mappedHandler = this.handlerMap.get(urlPath);
if (mappedHandler != null) {
if (mappedHandler != resolvedHandler) {
throw new IllegalStateException(
"Cannot map " + getHandlerDescription(handler) + " to URL path [" + urlPath +
"]: There is already " + getHandlerDescription(mappedHandler) + " mapped.");
}
}
else {
//未存在
if (urlPath.equals("/")) {
//"/"-->设置为roothandler
setRootHandler(resolvedHandler);
}
else if (urlPath.equals("/*")) {
//对"/*"的匹配设置默认的handler
setDefaultHandler(resolvedHandler);
}
else {
//其余的路径绑定关系则存入handlerMap
this.handlerMap.put(urlPath, resolvedHandler); }
}
}
}

主要的目的只是将绑定关系通过handlerMap存储罢了,那么我们肯定想知道这个registerHandler方法是如何被调用的,且看下文

SimpleUrlHandlerMapping-直接实现类

简单的路径映射处理类,我们先看下其在springmvc中的使用

<bean id="simpleBean" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<pros>
<pro key="/up">up</pro>
<pro key="/down">down</pro>
<pro key="/left">left</pro>
<pro key="/right">right</pro>
</pros>
</property>
</bean> <bean id="up" class="com.jing.springmvc.test.controller.UpController"> <bean id="down" class="com.jing.springmvc.test.controller.DownController"> <bean id="left" class="com.jing.springmvc.test.controller.LeftController"> <bean id="right" class="com.jing.springmvc.test.controller.RightController">

设置了上述属性后,实例后其会调用SimpleUrlHandlerMapping#setMappings()

	public void setMappings(Properties mappings) {
CollectionUtils.mergePropertiesIntoMap(mappings, this.urlMap);
}

在设置了上述的配置以后,SimpleUrlHandlerMapping则会调用AbstractHandlerMapping复写的方法initApplicationContext(),源码奉上

	@Override
public void initApplicationContext() throws BeansException {
//这在前文已知主要是获取interceptors
super.initApplicationContext();
//这里便是将上述的配置注册到AbstractUrlHandlerMapping#handlerMap中的入口
registerHandlers(this.urlMap);
}

转而看下上述的SimpleUrlHandlerMapping#registerHandlers(Map urlMap)方法

	protected void registerHandlers(Map<String, Object> urlMap) throws BeansException {
//urlMap不可为空
if (urlMap.isEmpty()) {
logger.warn("Neither 'urlMap' nor 'mappings' set on SimpleUrlHandlerMapping");
}
else {
for (Map.Entry<String, Object> entry : urlMap.entrySet()) {
String url = entry.getKey();
Object handler = entry.getValue();
// Prepend with slash if not already present.
if (!url.startsWith("/")) {
url = "/" + url;
}
// Remove whitespace from handler bean name.
if (handler instanceof String) {
handler = ((String) handler).trim();
}
//调用父类的注册方法
registerHandler(url, handler);
}
}
}

由以上的代码可知,SimpleUrlHandlerMapping只是对路径进行细心化的处理

  1. 对不以"/"开头的路径,加上"/"前缀

  2. 对beanName进行去除空字符的处理,且beanName必须是springmvc上下文存在的,否则在绑定的过程中会抛异常

BeanNameUrlHandlerMapping例子

<beans ...>

   <bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <bean id="/welcome.htm"
class="com.mkyong.common.controller.WelcomeController" /> <bean id="/streetName.htm"
class="com.mkyong.common.controller.StreetNameController" /> <bean id="/process*.htm"
class="com.mkyong.common.controller.ProcessController" /> </beans>

小结

1.AbstractUrlHandlerMapping主要是将请求路径绑定beanName,介绍了其直接实现类SimpleUrlHandlerMapping的注册步骤,比较简单,其余的实现类比如BeanNameUrlHandlerMapping会对以"/"开头的beanName注册,具体可自行去分析

2.SimpleUrlHandlerMappingBeanNameUrlHandlerMapping其基本都是对以/开头的路径绑定以org.springframework.web.servlet.mvc.Controller为接口实现类,前者间接关联,后者直接关联

SpringMVC源码情操陶冶-AbstractUrlHandlerMapping的更多相关文章

  1. SpringMVC源码情操陶冶-FreeMarker之web配置

    前言:本文不讲解FreeMarkerView视图的相关配置,其配置基本由FreeMarkerViewResolver实现,具体可参考>>>SpringMVC源码情操陶冶-ViewRe ...

  2. SpringMVC源码情操陶冶-DispatcherServlet

    本文对springmvc核心类DispatcherServlet作下简单的向导,方便博主与读者查阅 DispatcherServlet-继承关系 分析DispatcherServlet的继承关系以及主 ...

  3. SpringMVC源码情操陶冶-AnnotationDrivenBeanDefinitionParser注解解析器

    mvc:annotation-driven节点的解析器,是springmvc的核心解析器 官方注释 Open Declaration org.springframework.web.servlet.c ...

  4. SpringMVC源码情操陶冶-DispatcherServlet父类简析

    阅读源码有助于陶冶情操,本文对springmvc作个简单的向导 springmvc-web.xml配置 <servlet> <servlet-name>dispatch< ...

  5. SpringMVC源码情操陶冶-DispatcherServlet类简析(一)

    阅读源码有利于陶冶情操,此文承接前文SpringMVC源码情操陶冶-DispatcherServlet父类简析 注意:springmvc初始化其他内容,其对应的配置文件已被加载至beanFactory ...

  6. SpringMVC源码情操陶冶-DispatcherServlet简析(二)

    承接前文SpringMVC源码情操陶冶-DispatcherServlet类简析(一),主要讲述初始化的操作,本文将简单介绍springmvc如何处理请求 DispatcherServlet#doDi ...

  7. SpringMVC源码情操陶冶-HandlerAdapter适配器简析

    springmvc中对业务的具体处理是通过HandlerAdapter适配器操作的 HandlerAdapter接口方法 列表如下 /** * Given a handler instance, re ...

  8. SpringMVC源码情操陶冶-AbstractHandlerMethodMapping

    承接前文SpringMVC源码情操陶冶-AbstractHandlerMapping,本文将介绍如何注册HandlerMethod对象作为handler 类结构瞧一瞧 public abstract ...

  9. SpringMVC源码情操陶冶-RequestMappingHandlerAdapter适配器

    承接前文SpringMVC源码情操陶冶-HandlerAdapter适配器简析.RequestMappingHandlerAdapter适配器组件是专门处理RequestMappingHandlerM ...

随机推荐

  1. [Codeforces 696D] Legen...

    题目大意: 给出一些匹配串,要造一个长度不超过L的字符串,每个匹配串有自己的价值,匹配串每次出现在字符串里都会贡献一次价值...要求可能得到的最大价值. 匹配串总长不超200,L<=10^14, ...

  2. [bzoj3955] [WF2013]Surely You Congest

    首先最短路长度不同的人肯定不会冲突. 对于最短路长度相同的人,跑个最大流就行了..当然只有一个人就不用跑了 看起来会T得很惨..但dinic在单位网络里是O(m*n^0.5)的... #include ...

  3. [FZU1977] Pandora adventure

    来学插头DP了= = GDKOI前觉得不会考数位DP,GDOI前觉得插头DP用不上.. 结果令人伤感>_< 这题并不用增加状态.. 只要在形成环的时候,让形成环的位置在最后一个必走点之后, ...

  4. hdu_1011(Starship Troopers) 树形dp

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 题意:打洞洞收集脑子,你带领一个军队,洞洞互联成一棵树,每个洞中有一些bug,要全部杀死这些虫子 ...

  5. 什么是 core dump ? 以及如何使用gdb对 core dumped 进行调试

    什么是core dump?(down = 当) core的意思是:内存,dump的意思是:扔出来.堆出来. 开发和使用linux程序时,有时程序莫名其妙的down掉了,却没有任何的提示(有时候会提示c ...

  6. POJ 3278 Catch That Cow(模板——BFS)

    题目链接:http://poj.org/problem?id=3278 Description Farmer John has been informed of the location of a f ...

  7. 织梦dedecsm系统"企业简介"类单栏目模版如何修改和调用

    2013-1-12 14:46 | 发布者: moke | 栏目:dedecms教程        我们的模版里应该都有article_article.htm这个模版,这个模版是文章内容页模板,也就是 ...

  8. 什么是Linux主机?

    Linux主机是基于Linux内核的服务器操作系统配置的主机(常见Linux服务器操作系统如:Redhat,CentOS,Debian,FreeBSD,Ubentu等). Linux主机采用国内功能最 ...

  9. electron 学习笔记

    一.快速搭建一个electron 项目结构 # 克隆示例项目的仓库 $ git clone https://github.com/electron/electron-quick-start # 进入这 ...

  10. Core Graphics框架是Quartz的核心,也是内容描画的基本接口。

    Core Graphics框架是Quartz的核心,也是内容描画的基本接口.