SpringMVC源码情操陶冶-AbstractUrlHandlerMapping
承接前文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只是对路径进行细心化的处理
对不以"/"开头的路径,加上"/"前缀
对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.
SimpleUrlHandlerMapping和BeanNameUrlHandlerMapping其基本都是对以/开头的路径绑定以org.springframework.web.servlet.mvc.Controller为接口实现类,前者间接关联,后者直接关联
SpringMVC源码情操陶冶-AbstractUrlHandlerMapping的更多相关文章
- SpringMVC源码情操陶冶-FreeMarker之web配置
前言:本文不讲解FreeMarkerView视图的相关配置,其配置基本由FreeMarkerViewResolver实现,具体可参考>>>SpringMVC源码情操陶冶-ViewRe ...
- SpringMVC源码情操陶冶-DispatcherServlet
本文对springmvc核心类DispatcherServlet作下简单的向导,方便博主与读者查阅 DispatcherServlet-继承关系 分析DispatcherServlet的继承关系以及主 ...
- SpringMVC源码情操陶冶-AnnotationDrivenBeanDefinitionParser注解解析器
mvc:annotation-driven节点的解析器,是springmvc的核心解析器 官方注释 Open Declaration org.springframework.web.servlet.c ...
- SpringMVC源码情操陶冶-DispatcherServlet父类简析
阅读源码有助于陶冶情操,本文对springmvc作个简单的向导 springmvc-web.xml配置 <servlet> <servlet-name>dispatch< ...
- SpringMVC源码情操陶冶-DispatcherServlet类简析(一)
阅读源码有利于陶冶情操,此文承接前文SpringMVC源码情操陶冶-DispatcherServlet父类简析 注意:springmvc初始化其他内容,其对应的配置文件已被加载至beanFactory ...
- SpringMVC源码情操陶冶-DispatcherServlet简析(二)
承接前文SpringMVC源码情操陶冶-DispatcherServlet类简析(一),主要讲述初始化的操作,本文将简单介绍springmvc如何处理请求 DispatcherServlet#doDi ...
- SpringMVC源码情操陶冶-HandlerAdapter适配器简析
springmvc中对业务的具体处理是通过HandlerAdapter适配器操作的 HandlerAdapter接口方法 列表如下 /** * Given a handler instance, re ...
- SpringMVC源码情操陶冶-AbstractHandlerMethodMapping
承接前文SpringMVC源码情操陶冶-AbstractHandlerMapping,本文将介绍如何注册HandlerMethod对象作为handler 类结构瞧一瞧 public abstract ...
- SpringMVC源码情操陶冶-RequestMappingHandlerAdapter适配器
承接前文SpringMVC源码情操陶冶-HandlerAdapter适配器简析.RequestMappingHandlerAdapter适配器组件是专门处理RequestMappingHandlerM ...
随机推荐
- NowCoder牛客练习赛7-A.骰子的游戏 B.购物-优先队列
A.骰⼦的游戏 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K64bit IO Format: %lld 题目描述 在Alice和Bob面前的是两个骰 ...
- BZOJ1008: [HNOI2008]越狱-快速幂+取模
1008: [HNOI2008]越狱 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 8689 Solved: 3748 Description 监狱有 ...
- UEP-confirm和alert弹窗
function stuDel(){ var ds = ajaxgrid.getCheckedRecords(); if(ds.length==0){ $.alert("提示信息" ...
- [国嵌攻略][069][Bootm命令移植]
Bootloader作用 1.初始化软硬件 2.启动操作系统 内核分类 1.zImage 不加信息头的内核 2.uImage 加信息头后的内核,用bootm命令来启动 bootm作用 1.检测信息头: ...
- java中JFrame类中函数addWindowListener(new WindowAdapter)
转自:http://blog.csdn.net/datouniao1/article/details/46984987:侵删. 在java编写的过程中常常遇到样的一段代码: frame.addWind ...
- STM32小结
1.GPIO 电灯 推挽输出 PB5 2.GPIO 按键 浮空输入 PA0 3.写IO高电平 HAL_GPIO_WritePin(GPIOB,GPIO_Pin_5,1); 4.读取IO电平 HAL_G ...
- 数据库01创建表和DML语言
楼主用的数据库时mysql,用的时navacat for mysql. 数据库层面: 1.显示所有数据库 show databases; 2.创建数据库,名字叫lyh,编码为utf-8 create ...
- 启动tomcat时,一直卡在Deploying web application directory这块的解决方案
本来今天正常往服务器上扔一个tomcat 部署一个项目的, 最后再启动tomcat 的时候 发现项目一直都访问不了,看了一下日志: [root@iz8vbdzx7y7owm488t4d89z bin] ...
- dede的pagelist标签的listsize数字属性详解
转载▼http://blog.sina.com.cn/s/blog_a4f3bd4e01012c8n.html dede的pagelist标签的listsize数字属性详解.见远seo经常用织梦搭建各 ...
- 新版Azure Automation Account 浅析(一) --- 创建和Run As Account
去年年底Azure中国的Automation Account悄悄做了升级.新版本不管从功能还是end user experience方面都让人耳目一新.如果说升级前只是一个运行脚本的小工具,升级后的A ...