Springmvc入门(十五)Handler的查找

HandlerMapping的结构图

不论是Url注册还是@requestMapping都具有相同的父类。所以整体的查找的模板方法在父类AbstractHandlerMapping中,并且他还实现了查找拦截器的方法。查找Handler的方法也实现了,但具体还是在子类中。

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		//根据请求找到handler
		//getHandlerInternal模板方法,由子类实现
		//RequestMethodHandlerMapping的getHandlerInternal由父类AbstractHandlerMethodMapping实现
		//Url那边的getHandlerInternal由他们的父类AbstractUrlHandlerMapping实现
		Object handler = getHandlerInternal(request);
		//没找到则用默认
		if (handler == null) {
			handler = getDefaultHandler();
		}
		if (handler == null) {
			return null;
		}
		//判断handler是否是spring类型
		if (handler instanceof String) {
			String handlerName = (String) handler;
			//获取handler类的对象
			handler = obtainApplicationContext().getBean(handlerName);
		}
		//获取拦截器以及handler类的请求方法
		HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
		//跨境cors
		if (CorsUtils.isCorsRequest(request)) {
			CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
			CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
			CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
			executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
		}
		//返回
		return executionChain;
	}
	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		//HandlerExecutionChain是handler以及它的拦截器的一个类
		HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
				(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
		//请求的路径
		String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
		//获取该请求的拦截器集合
		for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
			if (interceptor instanceof MappedInterceptor) {
				MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
				if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
					chain.addInterceptor(mappedInterceptor.getInterceptor());
				}
			}
			else {
				chain.addInterceptor(interceptor);
			}
		}
		return chain;
	}

先看@RequestMapping的注解的是如何实现getHandlerInternal方法。getHandlerInternal对请求路径找到请求执行的条件,然后进行匹配,找到符合的执行条件,然后根据执行条件找到HandlerMethod。

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 = 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();
		}
	}
	
	protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
		List<Match> matches = new ArrayList<>();
		//通过url找到问题处理的条件
		List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
		//将匹配条件加入matches中
		if (directPathMatches != null) {
			addMatchingMappings(directPathMatches, matches, request);
		}
		//为空,则将所有匹配条件加入matches中
		if (matches.isEmpty()) {
			addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
		}
		
		if (!matches.isEmpty()) {
			//对条件进行比较
			Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
			//排序
			matches.sort(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);
		}
	}
	
	

@RequestMapping的请求查找就完成,Url这边只要是根据Map中保存的url与请求的进行对比,假设找到handler则返回,假设Mp的请求带*这种进行处理,然后找到handler,然后构建成HandlerExecutionChain(handler跟拦截器)对象。

    @Override
	@Nullable
	protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
		//获取请求路径
		String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
		//查找handler
		Object handler = lookupHandler(lookupPath, request);
		if (handler == null) {
			
			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 = obtainApplicationContext().getBean(handlerName);
				}
				validateHandler(rawHandler, 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 {
		// 从Map中根据url找到handler
		Object handler = this.handlerMap.get(urlPath);
		if (handler != null) {
			//查找handler的bean
			if (handler instanceof String) {
				String handlerName = (String) handler;
				handler = obtainApplicationContext().getBean(handlerName);
			}
			validateHandler(handler, request);
			//构建HandlerInterceptor
			return buildPathExposingHandler(handler, urlPath, urlPath, null);
		}

		//对带*的模式与url进行匹配
		List<String> matchingPatterns = new ArrayList<>();
		for (String registeredPattern : this.handlerMap.keySet()) {
			if (getPathMatcher().match(registeredPattern, urlPath)) {
				matchingPatterns.add(registeredPattern);
			}
			else if (useTrailingSlashMatch()) {
				if (!registeredPattern.endsWith("/") && getPathMatcher().match(registeredPattern + "/", urlPath)) {
					matchingPatterns.add(registeredPattern +"/");
				}
			}
		}

		String bestMatch = null;
		Comparator<String> patternComparator = getPathMatcher().getPatternComparator(urlPath);
		if (!matchingPatterns.isEmpty()) {
			matchingPatterns.sort(patternComparator);
			if (logger.isDebugEnabled()) {
				logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns);
			}
			bestMatch = matchingPatterns.get(0);
		}
		if (bestMatch != null) {
			handler = this.handlerMap.get(bestMatch);
			if (handler == null) {
				if (bestMatch.endsWith("/")) {
					handler = this.handlerMap.get(bestMatch.substring(0, bestMatch.length() - 1));
				}
				if (handler == null) {
					throw new IllegalStateException(
							"Could not find handler for best pattern match [" + bestMatch + "]");
				}
			}
			
			if (handler instanceof String) {
				String handlerName = (String) handler;
				handler = obtainApplicationContext().getBean(handlerName);
			}
			validateHandler(handler, request);
			String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestMatch, urlPath);

			Map<String, String> uriTemplateVariables = new LinkedHashMap<>();
			for (String matchingPattern : matchingPatterns) {
				if (patternComparator.compare(bestMatch, matchingPattern) == 0) {
					Map<String, String> vars = getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath);
					Map<String, String> decodedVars = getUrlPathHelper().decodePathVariables(request, vars);
					uriTemplateVariables.putAll(decodedVars);
				}
			}
			if (logger.isDebugEnabled()) {
				logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables);
			}
			return buildPathExposingHandler(handler, bestMatch, pathWithinMapping, uriTemplateVariables);
		}

		return null;
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值