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 ...
随机推荐
- hihoCoder #1094 : Lost in the City(枚举,微软苏州校招笔试 12月27日 )
#1094 : Lost in the City 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Little Hi gets lost in the city. He ...
- POJ 1659 Frogs' Neighborhood(可图性判定—Havel-Hakimi定理)【超详解】
Frogs' Neighborhood Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 9897 Accepted: 41 ...
- BZOJ 1411&&Vijos 1544 : [ZJOI2009]硬币游戏【递推,快速幂】
1411: [ZJOI2009]硬币游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 897 Solved: 394[Submit][Status ...
- Legal or Not(拓扑排序判环)
http://acm.hdu.edu.cn/showproblem.php?pid=3342 Legal or Not Time Limit: 2000/1000 MS (Java/Others) ...
- linux基本命令学习01
=============================================================================Unix/Linux最主要的应用领域是基础服务 ...
- Mybatis之基于XML的表之间映射
数据库表之间的关系有3种,一对一.一对多.多对多.既然是ORM,这肯定是必须有的.在学习EF的时候也有涉及,今天就是参考着EF的来学习下MyBatis的表关系映射. 一.准备工作 1.准备Model和 ...
- java中的分支结构 switch case的使用
switch(A),括号中A的取值只能是整型或者可以转换为整型的数值类型,比如byte.short.int.char.string(jdk1.7后加入)还有枚举:需要强调的是:long是不能用在swi ...
- 关于STM32驱动DS1302实时时钟的一点思考
之前用51驱动过DS1302,没用多久就输出了正确的时间.当时以为这块芯片其实没啥,很简单.但是现在用STM32做项目,用到同样的芯片,以为这有何难,只要把那个程序拿过来复制黏贴改一下IO设置不就行了 ...
- 用php怎样将图片gif转化为jpg
<?php $input= "link2.gif"; $output='test.jpg' ; $image=imagecreatefromgif($input); imag ...
- Hadoop问题:The auxService:mapreduce_shuffle does not exist
问题描述:The auxService:mapreduce_shuffle does not exist INFO mapreduce.Job: Task Id : attempt_146180833 ...