AbstractUrlHandlerMapping类功能简介说明
下文笔者将讲述AbstractUrlHandlerMapping类的相关简介说明,如下所示:
这里我们看到了之前说的Map对象,用来存储url和Handler之间的关系,
当Handler获取为String时需要从Bean容器中获取注入的实现类,
当然在查找过程中也会有模糊匹配等查找过程。
AbstractUrlHandlerMapping是AbstractHandlerMapping的子类 AbstractUrlHandlerMapping的功能:将beanName注册为handler对象。
registerHandler() 注册handler对象
//注册url和Bean的map,注册多个string的url到一个处理器中 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); } } ////注册url和Bean的map,将具体的Handler注入到url对应的map中 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. //如果Handler是String类型而且没有设置lazyInitHandlers则从springMVC容器中获取handler 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("/")) { if (logger.isInfoEnabled()) { logger.info("Root mapping to " + getHandlerDescription(handler)); } //"/"-->设置为roothandler setRootHandler(resolvedHandler); else if (urlPath.equals("/*")) { if (logger.isInfoEnabled()) { logger.info("Default mapping to " + getHandlerDescription(handler)); } //对"/*"的匹配设置默认的handler setDefaultHandler(resolvedHandler); } else { //其余的路径绑定关系则存入handlerMap this.handlerMap.put(urlPath, resolvedHandler); if (logger.isInfoEnabled()) { logger.info("Mapped URL path [" + urlPath + "] onto " + getHandlerDescription(handler)); } } } }
getHandlerInternal() 获取Handler
@Override protected Object getHandlerInternal(HttpServletRequest request) throws Exception { // 根据request获取url String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); // 根据url查找handler Object handler = lookupHandler(lookupPath, request); if (handler == null) { // 如果没有匹配到handler需要查找默认的,下面需要将PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE缓存到request // We need to care for the default handler directly, since we need to // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well. Object rawHandler = null; if ("/".equals(lookupPath)) { rawHandler = getRootHandler(); } if (rawHandler == null) { rawHandler = getDefaultHandler(); } if (rawHandler != null) { // Bean name or resolved handler? if (rawHandler instanceof String) { String handlerName = (String) rawHandler; rawHandler = getApplicationContext().getBean(handlerName); } // 预留的校验handler模板方法,没有使用 validateHandler(rawHandler, request); // 添加expose属性到request的拦截器 handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null); } } if (handler != null && logger.isDebugEnabled()) { logger.debug("Mapping [" + lookupPath + "] to " + handler); } else if (handler == null && logger.isTraceEnabled()) { logger.trace("No handler mapping found for [" + lookupPath + "]"); } return handler; } protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception { // Direct match? 直接根据url进行查找handler Object handler = this.handlerMap.get(urlPath); if (handler != null) { // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } validateHandler(handler, request); return buildPathExposingHandler(handler, urlPath, urlPath, null); } // Pattern match? 通过表达式进行匹配具体通过AntPathMatcher实现,具体后面分析 listmatchingPatterns = new ArrayList(); for (String registeredPattern : this.handlerMap.keySet()) { if (getPathMatcher().match(registeredPattern, urlPath)) { matchingPatterns.add(registeredPattern); } } String bestPatternMatch = null; //匹配规则 ComparatorpatternComparator = getPathMatcher().getPatternComparator(urlPath); if (!matchingPatterns.isEmpty()) { Collections.sort(matchingPatterns, patternComparator); if (logger.isDebugEnabled()) { logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns); } // order序号最小的优先级最高 bestPatternMatch = matchingPatterns.get(0); } if (bestPatternMatch != null) { handler = this.handlerMap.get(bestPatternMatch); // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } validateHandler(handler, request); String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPatternMatch, urlPath); // There might be multiple 'best patterns', let's make sure we have the correct URI template variables // for all of them Map uriTemplateVariables = new LinkedHashMap(); for (String matchingPattern : matchingPatterns) { if (patternComparator.compare(bestPatternMatch, matchingPattern) == 0) { Map vars = getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath); Map decodedVars = getUrlPathHelper().decodePathVariables(request, vars); uriTemplateVariables.putAll(decodedVars); } } if (logger.isDebugEnabled()) { logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables); } return buildPathExposingHandler(handler, bestPatternMatch, pathWithinMapping, uriTemplateVariables); } // No handler found... return null; } //用于给找到的Handler注册两个拦截器PathExposingHandlerInterceptor和UriTemplateVariablesHandlerInterceptor //这两个拦截器的的作用是将与当前url实际匹配的Pattern、匹配条件和url模板参数设置到request的属性中 protected Object buildPathExposingHandler(Object rawHandler, String bestMatchingPattern, String pathWithinMapping, Map uriTemplateVariables) { HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler); chain.addInterceptor(new PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping)); if (!CollectionUtils.isEmpty(uriTemplateVariables)) { chain.addInterceptor(new UriTemplateVariablesHandlerInterceptor(uriTemplateVariables)); } return chain; }getHandlerInternal首先是通过lookupHandler方法来查找Handler,
这里我们看到了之前说的Map对象,用来存储url和Handler之间的关系,
当Handler获取为String时需要从Bean容器中获取注入的实现类,
当然在查找过程中也会有模糊匹配等查找过程。
通过以上分析,我们可以得知: AbstractUrlHandlerMapping的功能: 将请求路径绑定beanName 它提供的功能是根据url从handlerMap中获取handler和注册url和handler的对应关系到handlerMap中
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。