Spring源码之请求路径匹配路由

在spring中,当一个请求过来的时候会做路径匹配,下面我们就从源码层面分析一下路径匹配。

示例:

@RequestMapping(value = "/user/{aid}/online/**", method = RequestMethod.GET)

我们一起看看这个方法是如何寻找的,和一些相应的工具类

1、入口

我的项目使用的是自动配置的RequestMappingHandlerMapping类,在getHandlerInternal()方法中:

HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);

上面这行是根据你的请求path和request去查找合适的method了。在项目启动的时候,Spring就把路径和对应的方法加载到了内存中。进入上面方法:

		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);
		}

可以看到如果根据lookupPath直接匹配上了,走第一个方法,如果没有,则需要根据规则匹配,走第二个方法。

mappingRegistry.getMappings().keySer()这个方法获取的类型为RequestMappingInfo类型,后面进入了RequestMappingInfo的getMatchingCondition()方法:

	public RequestMappingInfo getMatchingCondition(HttpServletRequest request) {
		RequestMethodsRequestCondition methods = this.methodsCondition.getMatchingCondition(request);
		ParamsRequestCondition params = this.paramsCondition.getMatchingCondition(request);
		HeadersRequestCondition headers = this.headersCondition.getMatchingCondition(request);
		ConsumesRequestCondition consumes = this.consumesCondition.getMatchingCondition(request);
		ProducesRequestCondition produces = this.producesCondition.getMatchingCondition(request);

		if (methods == null || params == null || headers == null || consumes == null || produces == null) {
			return null;
		}

		PatternsRequestCondition patterns = this.patternsCondition.getMatchingCondition(request);
		if (patterns == null) {
			return null;
		}

可以看到代码里面会查看各种条件是否匹配,包括,请求方法methods,参数params,请求头headers,还出入参类型等相关的consumers,produces等,最后一行就是我们要找的路径匹配patternsCondition.getMatchingCondition(request)。

这个方法会走到PatternRequestCondition的getMatchingPattern方法,然后调用如下方法,获取pattern:

		if (this.pathMatcher.match(pattern, lookupPath)) {
			return pattern;
		}

上面这个pathMatcher的类型就是AntPathMatcher类,就是通过调用AntPathMatcher类的match方法,查看是否匹配,然后返回pattern。

猜你喜欢

转载自blog.csdn.net/lz710117239/article/details/81226919