博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringMVC源码解读 - HandlerMapping - AbstractUrlHandlerMapping系列request分发
阅读量:7029 次
发布时间:2019-06-28

本文共 10858 字,大约阅读时间需要 36 分钟。

 

AbstractHandlerMapping实现HandlerMapping接口定的getHandler

  1. 提供getHandlerInternal模板方法给子类实现

  2. 如果没有获取Handler,则使用默认的defaultHandler

  3. 如果handler是string类型,从context获取实例

  4. 通过getHandlerExecutionChain封装handler,添加interceptor

// AbstractHandlerMapping

1     /** 2      * Look up a handler for the given request, falling back to the default 3      * handler if no specific one is found. 4      * @param request current HTTP request 5      * @return the corresponding handler instance, or the default handler 6      * @see #getHandlerInternal 7      */ 8     public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { 9         Object handler = getHandlerInternal(request);10         if (handler == null) {11             handler = getDefaultHandler();12         }13         if (handler == null) {14             return null;15         }16         // Bean name or resolved handler?17         if (handler instanceof String) {18             String handlerName = (String) handler;19             handler = getApplicationContext().getBean(handlerName);20         }21         return getHandlerExecutionChain(handler, request);22     }

// AbstractHandlerMapping

1     /** 2      * Build a HandlerExecutionChain for the given handler, including applicable interceptors. 3      * 

The default implementation simply builds a standard HandlerExecutionChain with 4 * the given handler, the handler mapping's common interceptors, and any {

@link MappedInterceptor}s 5 * matching to the current request URL. Subclasses may 6 * override this in order to extend/rearrange the list of interceptors. 7 *

NOTE: The passed-in handler object may be a raw handler or a pre-built 8 * HandlerExecutionChain. This method should handle those two cases explicitly, 9 * either building a new HandlerExecutionChain or extending the existing chain.10 *

For simply adding an interceptor, consider calling {

@code super.getHandlerExecutionChain}11 * and invoking {
@link HandlerExecutionChain#addInterceptor} on the returned chain object.12 * @param handler the resolved handler instance (never {
@code null})13 * @param request current HTTP request14 * @return the HandlerExecutionChain (never {
@code null})15 * @see #getAdaptedInterceptors()16 */17 protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {18 HandlerExecutionChain chain =19 (handler instanceof HandlerExecutionChain) ?20 (HandlerExecutionChain) handler : new HandlerExecutionChain(handler);21 22 chain.addInterceptors(getAdaptedInterceptors());23 24 String lookupPath = urlPathHelper.getLookupPathForRequest(request);25 for (MappedInterceptor mappedInterceptor : mappedInterceptors) {26 if (mappedInterceptor.matches(lookupPath, pathMatcher)) {27 chain.addInterceptor(mappedInterceptor.getInterceptor());28 }29 }30 31 return chain;32 }

 

接下来看看AbstractUrlHandlerMapping实现的getHandlerInternal

// AbstractUrlHandlerMapping

1     /** 2      * Look up a handler for the URL path of the given request. 3      * @param request current HTTP request 4      * @return the handler instance, or {
@code null} if none found 5 */ 6 @Override 7 protected Object getHandlerInternal(HttpServletRequest request) throws Exception { 8 // 根据request获取url 9 String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);10 // 根据url查找handler11 Object handler = lookupHandler(lookupPath, request);12 if (handler == null) {13 // 如果没有匹配到handler需要查找默认的,下面需要将PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE缓存到request14 // We need to care for the default handler directly, since we need to15 // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.16 Object rawHandler = null;17 if ("/".equals(lookupPath)) {18 rawHandler = getRootHandler();19 }20 if (rawHandler == null) {21 rawHandler = getDefaultHandler();22 }23 if (rawHandler != null) {24 // Bean name or resolved handler?25 if (rawHandler instanceof String) {26 String handlerName = (String) rawHandler;27 rawHandler = getApplicationContext().getBean(handlerName);28 }29 // 预留的校验handler模板方法,没有使用30 validateHandler(rawHandler, request);31 // 添加expose属性到request的拦截器32 handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);33 }34 }35 if (handler != null && logger.isDebugEnabled()) {36 logger.debug("Mapping [" + lookupPath + "] to " + handler);37 }38 else if (handler == null && logger.isTraceEnabled()) {39 logger.trace("No handler mapping found for [" + lookupPath + "]");40 }41 return handler;42 }

 

// AbstractUrlHandlerMapping

1     /** 2      * Look up a handler instance for the given URL path. 3      * 

Supports direct matches, e.g. a registered "/test" matches "/test", 4 * and various Ant-style pattern matches, e.g. a registered "/t*" matches 5 * both "/test" and "/team". For details, see the AntPathMatcher class. 6 *

Looks for the most exact pattern, where most exact is defined as 7 * the longest path pattern. 8 * @param urlPath URL the bean is mapped to 9 * @param request current HTTP request (to expose the path within the mapping to)10 * @return the associated handler instance, or {

@code null} if not found11 * @see #exposePathWithinMapping12 * @see org.springframework.util.AntPathMatcher13 */14 protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {15 // Direct match? 直接根据url进行查找handler16 Object handler = this.handlerMap.get(urlPath);17 if (handler != null) {18 // Bean name or resolved handler?19 if (handler instanceof String) {20 String handlerName = (String) handler;21 handler = getApplicationContext().getBean(handlerName);22 }23 validateHandler(handler, request);24 return buildPathExposingHandler(handler, urlPath, urlPath, null);25 }26 // Pattern match? 通过表达式进行匹配具体通过AntPathMatcher实现,具体后面分析27 List
matchingPatterns = new ArrayList
();28 for (String registeredPattern : this.handlerMap.keySet()) {29 if (getPathMatcher().match(registeredPattern, urlPath)) {30 matchingPatterns.add(registeredPattern);31 }32 }33 String bestPatternMatch = null;34 Comparator
patternComparator = getPathMatcher().getPatternComparator(urlPath);35 if (!matchingPatterns.isEmpty()) {36 Collections.sort(matchingPatterns, patternComparator);37 if (logger.isDebugEnabled()) {38 logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns);39 }40 // order序号最小的优先级最高41 bestPatternMatch = matchingPatterns.get(0);42 }43 if (bestPatternMatch != null) {44 handler = this.handlerMap.get(bestPatternMatch);45 // Bean name or resolved handler?46 if (handler instanceof String) {47 String handlerName = (String) handler;48 handler = getApplicationContext().getBean(handlerName);49 }50 validateHandler(handler, request);51 String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPatternMatch, urlPath);52 53 // There might be multiple 'best patterns', let's make sure we have the correct URI template variables54 // for all of them55 Map
uriTemplateVariables = new LinkedHashMap
();56 for (String matchingPattern : matchingPatterns) {57 if (patternComparator.compare(bestPatternMatch, matchingPattern) == 0) {58 Map
vars = getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath);59 Map
decodedVars = getUrlPathHelper().decodePathVariables(request, vars);60 uriTemplateVariables.putAll(decodedVars);61 }62 }63 if (logger.isDebugEnabled()) {64 logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables);65 }66 return buildPathExposingHandler(handler, bestPatternMatch, pathWithinMapping, uriTemplateVariables);67 }68 // No handler found...69 return null;70 }

 

 

设计用于校验Handler,实际什么都没做,包括子类.

1     /** 2      * Validate the given handler against the current request. 3      * 

The default implementation is empty. Can be overridden in subclasses, 4 * for example to enforce specific preconditions expressed in URL mappings. 5 * @param handler the handler object to validate 6 * @param request current HTTP request 7 * @throws Exception if validation failed 8 */ 9 protected void validateHandler(Object handler, HttpServletRequest request) throws Exception {10 }

 

封装handler为HandlerExecutionChain,并添加PathExposingHandlerInterceptor和UriTemplateVariablesHandlerInterceptor拦截器.

1     /** 2      * Build a handler object for the given raw handler, exposing the actual 3      * handler, the {
@link #PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE}, as well as 4 * the {
@link #URI_TEMPLATE_VARIABLES_ATTRIBUTE} before executing the handler. 5 *

The default implementation builds a {

@link HandlerExecutionChain} 6 * with a special interceptor that exposes the path attribute and uri template variables 7 * @param rawHandler the raw handler to expose 8 * @param pathWithinMapping the path to expose before executing the handler 9 * @param uriTemplateVariables the URI template variables, can be {
@code null} if no variables found10 * @return the final handler object11 */12 protected Object buildPathExposingHandler(Object rawHandler, String bestMatchingPattern,13 String pathWithinMapping, Map
uriTemplateVariables) {14 15 HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler);16 chain.addInterceptor(new PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping));17 if (!CollectionUtils.isEmpty(uriTemplateVariables)) {18 chain.addInterceptor(new UriTemplateVariablesHandlerInterceptor(uriTemplateVariables));19 }20 return chain;21 }

 

转载于:https://www.cnblogs.com/leftthen/p/5208376.html

你可能感兴趣的文章
【译】OpenDaylight控制器:YANG Schema和Model
查看>>
C#访问修饰符(public,private,protected,internal,sealed,abstract)
查看>>
android消息线程和消息队列
查看>>
EXCEL中计算不重复单元格的个数
查看>>
二层设备与三层设备的区别--总结
查看>>
安装pytorch成功但cuda不可用
查看>>
unity__DrawCall的理解
查看>>
springboot架构下运用shiro后在configuration,通过@Value获取不到值,总是为null
查看>>
SQLServer 数据库镜像+复制切换方案
查看>>
Postman初探
查看>>
仿淘宝头像上传功能(一)——前端篇。
查看>>
Eclipse通过集成svn实现版本控制
查看>>
OS开发过程中常用开源库
查看>>
关于在多个UItextield切换焦点
查看>>
hdu 2768
查看>>
git记住用户名密码
查看>>
ElasticSearch(2)-安装ElasticSearch
查看>>
从mysql数据表中随机取出一条记录
查看>>
ORACLE 锁表处理,解锁释放session
查看>>
深海机器人问题
查看>>