springMVC源码分析--AbstractHandlerMethodMapping获取url和HandlerMethod对应关系(十)
在之前的博客springMVC源码分析--AbstractHandlerMapping(二)中我们介绍了AbstractHandlerMethodMapping的父类AbstractHandlerMapping,其定义了抽象方法getHandlerInternal(HttpServletRequest request),我看一下其在AbstractHandlerMethodMapping中的实现。
在AbstractHandlerMethodMapping中getHandlerInternal的实现如下:
//根据request来获取HandlerMethod
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
//获取请求连接
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
if (logger.isDebugEnabled()) {
logger.debug("Looking up handler method for path " + lookupPath);
}
//读锁
this.mappingRegistry.acquireReadLock();
try {
//获取HandlerMethod
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
if (logger.isDebugEnabled()) {
if (handlerMethod != null) {
logger.debug("Returning handler method [" + handlerMethod + "]");
}
else {
logger.debug("Did not find handler method for [" + lookupPath + "]");
}
}
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
this.mappingRegistry.releaseReadLock();
}
}
具体的实现是在lookupHandlerMethod中,最终是在mappingRegistry中获取HandlerMethod,mappingRegistry可以看似是一个Map结构(其实其包含了3个map),包含了url和HandlerMethod的对应关系。
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
List<Match> matches = new ArrayList<Match>();
//从mappingRegistry中获取directPathMatches匹配关系
List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
if (directPathMatches != null) {
addMatchingMappings(directPathMatches, matches, request);
}
if (matches.isEmpty()) {
// No choice but to go through all mappings...
addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
}
//最终返回HandlerMethod
if (!matches.isEmpty()) {
Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
Collections.sort(matches, comparator);
if (logger.isTraceEnabled()) {
logger.trace("Found " + matches.size() + " matching mapping(s) for [" +
lookupPath + "] : " + matches);
}
Match bestMatch = matches.get(0);
if (matches.size() > 1) {
if (CorsUtils.isPreFlightRequest(request)) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
Match secondBestMatch = matches.get(1);
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.handlerMethod.getMethod();
Method m2 = secondBestMatch.handlerMethod.getMethod();
throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path '" +
request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");
}
}
handleMatch(bestMatch.mapping, lookupPath, request);
return bestMatch.handlerMethod;
}
else {
return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
}
}
以下几个方法是在查找url和HandlerMethod的过程中一些帮助实现。
private void addMatchingMappings(Collection<T> mappings, List<Match> matches, HttpServletRequest request) {
for (T mapping : mappings) {
T match = getMatchingMapping(mapping, request);
if (match != null) {
matches.add(new Match(match, this.mappingRegistry.getMappings().get(mapping)));
}
}
}
//在子类中实现
protected abstract T getMatchingMapping(T mapping, HttpServletRequest request);
protected abstract Comparator<T> getMappingComparator(HttpServletRequest request);
protected void handleMatch(T mapping, String lookupPath, HttpServletRequest request) {
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, lookupPath);
}
//在子类中实现
protected HandlerMethod handleNoMatch(Set<T> mappings, String lookupPath, HttpServletRequest request)
throws Exception {
return null;
}
springMVC源码分析--AbstractHandlerMethodMapping获取url和HandlerMethod对应关系(十)的更多相关文章
- springMVC源码分析--AbstractHandlerMethodMapping注册url和HandlerMethod对应关系(十一)
在上一篇博客springMVC源码分析--AbstractHandlerMethodMapping获取url和HandlerMethod对应关系(十)中我们简单地介绍了获取url和HandlerMet ...
- springMVC源码分析--DispatcherServlet请求获取及处理
在之前的博客springMVC源码分析--容器初始化(二)DispatcherServlet中我们介绍过DispatcherServlet,是在容器初始化过程中出现的,我们之前也说过Dispatche ...
- springMVC源码分析--HandlerMapping(一)
HandlerMapping的工作就是为每个请求找到合适的请求找到一个处理器handler,其实现机制简单来说就是维持了一个url到Controller关系的Map结构,其提供的实际功能也是根据req ...
- 框架-springmvc源码分析(二)
框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...
- 框架-springmvc源码分析(一)
框架-springmvc源码分析(一) 参考: http://www.cnblogs.com/heavenyes/p/3905844.html#a1 https://www.cnblogs.com/B ...
- springMVC源码分析--ControllerClassNameHandlerMapping(九)
在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping ...
- springMVC源码分析--AbstractDetectingUrlHandlerMapping(五)
上一篇博客springMVC源码分析--AbstractUrlHandlerMapping(三)中我们介绍了AbstractUrlHandlerMapping,主要介绍了一个handlerMap的ur ...
- springMVC源码分析--SimpleUrlHandlerMapping(四)
上一篇博客springMVC源码分析--AbstractUrlHandlerMapping(三)中我们介绍了AbstractUrlHandlerMapping,主要介绍了一个handlerMap的ur ...
- springMVC源码分析--AbstractUrlHandlerMapping(三)
上一篇博客springMVC源码分析--AbstractHandlerMapping(二)中我们介绍了AbstractHandlerMapping了,接下来我们介绍其子类AbstractUrlHand ...
随机推荐
- MyBatis基础学习笔记--摘录
1.MyBatis是什么? MyBatis源自于IBatis,是一个持久层框架,封装了jdbc操作数据库的过程,使得开发者只用关心sql语句,无需关心驱动加载.连接,创建statement,手动设置参 ...
- 学习HTML的第二次课
1.图片 <img / > 图片的格式: 1.1BMP 占用空间大,颜色丰富. 1.2JPEG 有损压缩,占用空间较小. 1.3GIF 多帧动图,支持透明色. 1.4PNG 无损压缩,位图 ...
- python3全栈开发-异常处理
一. 什么是异常 异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止),在python中,错误触发的异常如下 而错误分成两种 ...
- [LeetCode] Remove 9 移除9
Start from integer 1, remove any integer that contains 9 such as 9, 19, 29... So now, you will have ...
- [LeetCode] Image Smoother 图片平滑器
Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother t ...
- 机器学习基石:02 Learning to Answer Yes/No
Perceptron Learning Algorithm 感知器算法, 本质是二元线性分类算法,即用一条线/一个面/一个超平面将1,2维/3维/4维及以上数据集根据标签的不同一分为二. 算法确定后, ...
- Linux下 Apache Vhost 配置 防止403
首先,贴一份正确的配置(最简单的) <VirtualHost *:80> DocumentRoot /home/ubuntu/www/spider/public ServerName sp ...
- 洛谷P1397 [NOI2013]矩阵游戏
矩阵快速幂+费马小定理 矩阵也是可以跑费马小定理的,但是要注意这个: (图是盗来的QAQ) 就是说如果矩阵a[i][i]都是相等的,那么就是mod p 而不是mod p-1了 #include< ...
- HDU 4787 GRE Words Revenge
Description Now Coach Pang is preparing for the Graduate Record Examinations as George did in 2011. ...
- [Spoj]Counting Divisors (cube)
来自FallDream的博客,未经允许,请勿转载,谢谢. 设d(x)表示x的约数个数,求$\sum_{i=1}^{n}d(i^{3})$ There are 5 Input files. - Inpu ...