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基础学习笔记--自总结
一.MyBatis和jdbc的区别 jdbc的过程包括: 1.加载数据库驱动. 2.建立数据库连接. 3.编写sql语句. 4.获取Statement:(Statement.PrepareStatem ...
- Oracle数据库基础练习题
--1.查询和SMITH相同部门的员工姓名和雇用日期select ename,hiredate from emp where deptno=(select deptno from emp where ...
- ActiveMQ笔记:一个高稳定,可扩展的的部署方案
本文介绍一个笔者在实际工作中的实施的基于ActiveMQ的一个高稳定,可扩展的异步消息系统. ActiveMQ是一个成熟的基于Java语言的开源消息系统,在实际应用中被大量使用.ActiveMQ在系统 ...
- 获取Avrix上Computer Vision and Pattern Recognition的论文,进一步进行统计分析。
此文主要记录我在18年寒假期间,收集Avrix论文的总结 寒假生活题外 在寒假期间,爸妈每天让我每天跟着他们6点起床,一起吃早点收拾,每天7点也就都收拾差不多. 早晨的时光是人最清醒的时刻,而 ...
- [HNOI2004]敲砖块
题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示. 14 15 4 3 23 33 33 7 ...
- 基于vfs实现自己的文件系统
1.Linux 文件系统组成结构 linux文件系统有两个重要的特点:一个是文件系统抽象出了一个通用文件表示层--虚拟文件系统或称做VFS.另外一个重要特点就是它的文件系统支持动态安装(或说挂载等), ...
- Codeforces 671 D. Roads in Yusland
题目描述 Mayor of Yusland just won the lottery and decided to spent money on something good for town. Fo ...
- 【Codeforces 851D Arpa and a list of numbers】
Arpa的数列要根据GCD变成好数列. ·英文题,述大意: 给出一个长度为n(n<=5000000)的序列,其中的元素a[i]<=106,然后输入两个数x,y(x,y<=1 ...
- [poj1279]Art Gallery
题意:求多边形的核的面积. 敲一下半平面交模板........ 然后我wa了一早上就因为写了%lf 不知道poj什么破机制还不能用lf的,真的想跳楼 #include<iostream> ...
- java continue与break区别
在循环体中跳出循环语句有continue与break语句 continue:跳出本次循环,包括本次循环continue后面的语句, break:跳出循环体,就是说一遇到break循环就结束. 代码: ...