requestMappingHandlerMapping的原理

在这里插入图片描述

  • 这些类分别的作用是啥?为啥要这样设计
#初始化config对象,接着调用父类的afterPropertiesSet方法
	public void afterPropertiesSet() {
	# RequestMappingInfo用于保存Request mapping information.里面有RequestMapping注释中的各种condition,
	#比如:patternsCondition,methodsCondition,paramsCondition等
	#RequestMappingInfo.BuilderConfiguration为@RequestMapping中配置项的容器,用于request  mapping解析的过程中
		this.config = new RequestMappingInfo.BuilderConfiguration();
		#URL path matching的帮助类
		this.config.setUrlPathHelper(getUrlPathHelper());
		#用于path matching,定义匹配string的策略接口
		this.config.setPathMatcher(getPathMatcher());
		#是否开启 pattern matching中的前缀匹配
		this.config.setSuffixPatternMatch(useSuffixPatternMatch());
		#是否开启PatternsRequestCondition中的尾随斜杠
		this.config.setTrailingSlashMatch(useTrailingSlashMatch());
		#是否开启后缀访问,方法上的/hello也会匹配到/hello.json路径
		this.config.setRegisteredSuffixPatternMatch(useRegisteredSuffixPatternMatch());
		#设置ProducesRequestCondition需要的内容管理器
		this.config.setContentNegotiationManager(getContentNegotiationManager());
		#调用父类的afterPropertiesSet方法

		super.afterPropertiesSet();
	}

#接下来会调用org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#afterPropertiesSet的方法
public void afterPropertiesSet() {
		initHandlerMethods();
	}


protected void initHandlerMethods() {
#遍历获得到的beanName
		for (String beanName : getCandidateBeanNames()) {
		#如果beanName没有以SCOPED_TARGET_NAME_PREFIX = "scopedTarget."起始
			if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
				processCandidateBean(beanName);
			}
		}
		handlerMethodsInitialized(getHandlerMethods());
	}

#detectHandlerMethodsInAncestorContexts默认为false,代表不会从springMVC的父容器中获取CandidateBeanNames,否则从上下文对象中获取所有的对象
	protected String[] getCandidateBeanNames() {
		return (this.detectHandlerMethodsInAncestorContexts ?
				BeanFactoryUtils.beanNamesForTypeIncludingAncestors(obtainApplicationContext(), Object.class) :
				obtainApplicationContext().getBeanNamesForType(Object.class));
	}
	#返回上下对象
protected final ApplicationContext obtainApplicationContext() {
		ApplicationContext applicationContext = getApplicationContext();
		Assert.state(applicationContext != null, "No ApplicationContext");
		return applicationContext;
	}
	#获得当前对象运行在的上下文对象
		public final ApplicationContext getApplicationContext() throws IllegalStateException {
		if (this.applicationContext == null && isContextRequired()) {
			throw new IllegalStateException(
					"ApplicationObjectSupport instance [" + this + "] does not run in an ApplicationContext");
		}
		return this.applicationContext;
	}


		protected void processCandidateBean(String beanName) {
		Class<?> beanType = null;
		try {
		#根据beanName获得在相应的类型
			beanType = obtainApplicationContext().getType(beanName);
		}
		catch (Throwable ex) {
			// An unresolvable bean type, probably from a lazy bean - let's ignore it.
			if (logger.isTraceEnabled()) {
				logger.trace("Could not resolve type for bean '" + beanName + "'", ex);
			}
		}
		#如果是handler类型,isHandler为抽象方法,具体实现在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#isHandler,
		#如果该beanType上有@controller或者@RequestMapping注解信息
		if (beanType != null && isHandler(beanType)) {
		#加载该handler中的所有handlerMethod方法
			detectHandlerMethods(beanName);
		}
	}

#获取使用Controller和RequestMapping注释的类
	protected boolean isHandler(Class<?> beanType) {
	#AnnotatedElementUtils为操作注解的工具类
		return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
				AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
	}

#
	protected void detectHandlerMethods(Object handler) {
	#如果handler为string,则根据beanName获取handlerType,否则获取类型
		Class<?> handlerType = (handler instanceof String ?
				obtainApplicationContext().getType((String) handler) : handler.getClass());

		if (handlerType != null) {
		#返回cglib代理类的原始类
			Class<?> userType = ClassUtils.getUserClass(handlerType);
		#返回处理后的requestMappingInfo
			Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
					(MethodIntrospector.MetadataLookup<T>) method -> {
						try {
							return getMappingForMethod(method, userType);
						}
						catch (Throwable ex) {
							throw new IllegalStateException("Invalid mapping on handler class [" +
									userType.getName() + "]: " + method, ex);
						}
					});
			if (logger.isTraceEnabled()) {
				logger.trace(formatMappings(userType, methods));
			}
			methods.forEach((method, mapping) -> {
				Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
				#为抽象方法,具体实现在requestmappinghandlermapping类中
				registerHandlerMethod(handler, invocableMethod, mapping);
			});
		}
	}

#获取类对象
	public static Class<?> getUserClass(Class<?> clazz) {
		if (clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
			Class<?> superclass = clazz.getSuperclass();
			if (superclass != null && superclass != Object.class) {
				return superclass;
			}
		}
		return clazz;
	}

#该类中保存mapping和handlerMethod之间的关系
#又是registry!!!    
	class MappingRegistry {

		private final Map<T, MappingRegistration<T>> registry = new HashMap<>();

		private final Map<T, HandlerMethod> mappingLookup = new LinkedHashMap<>();

		private final MultiValueMap<String, T> urlLookup = new LinkedMultiValueMap<>();

		private final Map<String, List<HandlerMethod>> nameLookup = new ConcurrentHashMap<>();

		private final Map<HandlerMethod, CorsConfiguration> corsLookup = new ConcurrentHashMap<>();

		private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    }

	public static <T> Map<Method, T> selectMethods(Class<?> targetType, final MetadataLookup<T> metadataLookup) {
		final Map<Method, T> methodMap = new LinkedHashMap<>();
		Set<Class<?>> handlerTypes = new LinkedHashSet<>();
		Class<?> specificHandlerType = null;

		if (!Proxy.isProxyClass(targetType)) {
			specificHandlerType = ClassUtils.getUserClass(targetType);
			handlerTypes.add(specificHandlerType);
		}
		handlerTypes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetType));

		for (Class<?> currentHandlerType : handlerTypes) {
			final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType);

			ReflectionUtils.doWithMethods(currentHandlerType, method -> {
				Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
				T result = metadataLookup.inspect(specificMethod);
				if (result != null) {
					Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
					if (bridgedMethod == specificMethod || metadataLookup.inspect(bridgedMethod) == null) {
						methodMap.put(specificMethod, result);
					}
				}
			}, ReflectionUtils.USER_DECLARED_METHODS);
		}

		return methodMap;
	}

	protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
		RequestMappingInfo info = createRequestMappingInfo(method);
		#如果方法的info不为空
		if (info != null) {
		#获取类信息的typeInfo
			RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
			if (typeInfo != null) {
			#合并类,方法上标注的requestMapping和
				info = typeInfo.combine(info);
			}
			String prefix = getPathPrefix(handlerType);
			if (prefix != null) {
	#使用build后的RequestMappingInfo对象合并info
				info = RequestMappingInfo.paths(prefix).options(this.config).build().combine(info);
			}
		}
		return info;
	}

	private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
	#获得element中@RequestMapping注解的对象
		RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
		#如果element为class,返回Class的RequestCondition
		#如果element为method,返回method的RequestCondition
		RequestCondition<?> condition = (element instanceof Class ?
				getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
				#根据requestMapping和condition创建RequestMappingInfo对象
		return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
	}

#返回null的RequestCondition
protected RequestCondition<?> getCustomTypeCondition(Class<?> handlerType) {
		return null;
	}
#返回null的RequestCondition
	protected RequestCondition<?> getCustomMethodCondition(Method method) {
		return null;
	}

#接口的
	protected RequestMappingInfo createRequestMappingInfo(
			RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) {
#使用build模式将requestMapping和customCondition的信息封装到RequestMappingInfo里面
		RequestMappingInfo.Builder builder = RequestMappingInfo
				.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
				.methods(requestMapping.method())
				.params(requestMapping.params())
				.headers(requestMapping.headers())
				.consumes(requestMapping.consumes())
				.produces(requestMapping.produces())
				.mappingName(requestMapping.name());
		if (customCondition != null) {
			builder.customCondition(customCondition);
		}
		return builder.options(this.config).build();
	}
#org.springframework.web.servlet.mvc.method.RequestMappingInfo#combine
	public RequestMappingInfo combine(RequestMappingInfo other) {
	#如果当前对象的name和other中的name都不为空,则返回name1#name2,放回不为空的name
		String name = combineNames(other);
    #如果两者的patterns都不为空,则使用org.springframework.util.AntPathMatcher#combine对两个进行combine,否则放回不为空的patterns
		PatternsRequestCondition patterns = this.patternsCondition.combine(other.patternsCondition);
		#将两个方法methodConditons中的方法合并为set集合,使用set新疆新的
		RequestMethodsRequestCondition methods = this.methodsCondition.combine(other.methodsCondition);
		#将两个paramsRequest中的expression进行合并为set,使用set新建ParamsRequestCondition
		ParamsRequestCondition params = this.paramsCondition.combine(other.paramsCondition);
		#逻辑同上
		HeadersRequestCondition headers = this.headersCondition.combine(other.headersCondition);
		#如果other中consumesCondition的expressions不为空,
		#返回给other对象的consumesCondition,否则放回this对象的consumesCondition
		#如果method mapping中的的consumer存在,返回给方法的配置,否则返回给类上的配置
		ConsumesRequestCondition consumes = this.consumesCondition.combine(other.consumesCondition);
		#produces同上,以方法的为主
		ProducesRequestCondition produces = this.producesCondition.combine(other.producesCondition);
		#合并holder中的condition
		RequestConditionHolder custom = this.customConditionHolder.combine(other.customConditionHolder);
	    #使用合并后的结果新建RequestMappingInfo
		return new RequestMappingInfo(name, patterns,
				methods, params, headers, consumes, produces, custom.getCondition());
	}

	public PatternsRequestCondition combine(PatternsRequestCondition other) {
		Set<String> result = new LinkedHashSet<>();
		if (!this.patterns.isEmpty() && !other.patterns.isEmpty()) {
		#如果方法和class上的path都不为空,使用笛卡尔积形式,
		#利用pathMatcher对其进行combine后放入set中
			for (String pattern1 : this.patterns) {
				for (String pattern2 : other.patterns) {
					result.add(this.pathMatcher.combine(pattern1, pattern2));
				}
			}
		}
		#否则,如果当前的path不为空,放回当前path
		else if (!this.patterns.isEmpty()) {
			result.addAll(this.patterns);
		}
		#other不为空,返回other的path
		else if (!other.patterns.isEmpty()) {
			result.addAll(other.patterns);
		}
		#两者都为空,返回空串
		else {
			result.add("");
		}
		#将当前PatternsRequestCondition中的信息和合并后的结果result重新生成新的PatternsRequestCondition对象
		return new PatternsRequestCondition(result, this);
	}

	private PatternsRequestCondition(Set<String> patterns, PatternsRequestCondition other) {
		this.patterns = patterns;
		this.pathHelper = other.pathHelper;
		this.pathMatcher = other.pathMatcher;
		this.useSuffixPatternMatch = other.useSuffixPatternMatch;
		this.useTrailingSlashMatch = other.useTrailingSlashMatch;
		this.fileExtensions.addAll(other.fileExtensions);
	}
#org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition#combine
	public RequestMethodsRequestCondition combine(RequestMethodsRequestCondition other) {
		Set<RequestMethod> set = new LinkedHashSet<>(this.methods);
		#合并两个methods
		set.addAll(other.methods);
		return new RequestMethodsRequestCondition(set);
	}
#org.springframework.web.servlet.mvc.condition.ParamsRequestCondition#combine
	public ParamsRequestCondition combine(ParamsRequestCondition other) {
		Set<ParamExpression> set = new LinkedHashSet<>(this.expressions);
		#合并expressions
		set.addAll(other.expressions);
		return new ParamsRequestCondition(set);
	}

#org.springframework.web.servlet.mvc.condition.HeadersRequestCondition#combine
	public HeadersRequestCondition combine(HeadersRequestCondition other) {
		Set<HeaderExpression> set = new LinkedHashSet<>(this.expressions);
		#合并header中的信息,
		set.addAll(other.expressions);
		return new HeadersRequestCondition(set);
	}
#org.springframework.web.servlet.mvc.condition.ConsumesRequestCondition#combine
public ConsumesRequestCondition combine(ConsumesRequestCondition other) {
		return (!other.expressions.isEmpty() ? other : this);
	}
#org.springframework.web.servlet.mvc.condition.ProducesRequestCondition#combine
public ProducesRequestCondition combine(ProducesRequestCondition other) {
		return (!other.expressions.isEmpty() ? other : this);
	}

	public RequestConditionHolder combine(RequestConditionHolder other) {
	#两者都为空,返回空,两者中任意一个不为空,返回不为空的那个
		if (this.condition == null && other.condition == null) {
			return this;
		}
		else if (this.condition == null) {
			return other;
		}
		else if (other.condition == null) {
			return this;
		}
		else {
		#判断两者类型是否相等
			assertEqualConditionTypes(this.condition, other.condition);
		#两者都不为空,进行合并
			RequestCondition<?> combined = (RequestCondition<?>) this.condition.combine(other.condition);
		#使用组合后的结果,新建RequestConditionHolder对象
			return new RequestConditionHolder(combined);
		}
	}

#org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#getPathPrefix
	String getPathPrefix(Class<?> handlerType) {
	#遍历所有的pathPrefixes集合
		for (Map.Entry<String, Predicate<Class<?>>> entry : this.pathPrefixes.entrySet()) {
	#如果当前的controller类型符合predict
			if (entry.getValue().test(handlerType)) {
				String prefix = entry.getKey();
	#embeddedValueResolver为org.springframework.util.StringValueResolver
				if (this.embeddedValueResolver != null) {
	#使用该resolver解析prefix
					prefix = this.embeddedValueResolver.resolveStringValue(prefix);
				}
				return prefix;
			}
		}
		return null;
	}

#org.springframework.web.servlet.mvc.method.RequestMappingInfo#paths
	public static Builder paths(String... paths) {
	#将path封装到DefaultBuilder里面
		return new DefaultBuilder(paths);
	}
	
#org.springframework.web.servlet.mvc.method.RequestMappingInfo.DefaultBuilder#options返回默认的build对象
	public Builder options(BuilderConfiguration options) {
			this.options = options;
			return this;
		}
#org.springframework.web.servlet.mvc.method.RequestMappingInfo.DefaultBuilder#build,
#使用build模式创建RequestMappingInfo
		public RequestMappingInfo build() {
		#ContentNegotiationManager为确定request中的media type的核心类
			ContentNegotiationManager manager = this.options.getContentNegotiationManager();
#根据当前RequestMappingInfo中的封装好的对象,创建PatternsRequestCondition对象
			PatternsRequestCondition patternsCondition = new PatternsRequestCondition(
					this.paths, this.options.getUrlPathHelper(), this.options.getPathMatcher(),
					this.options.useSuffixPatternMatch(), this.options.useTrailingSlashMatch(),
					this.options.getFileExtensions());
#使用处理后的参数重新创建RequestMappingInfo对象
#RequestMappingInfo保存所有的requestmapping信息,
#在requestmappingInfo中使用RequestCondition接口不同实现类
			return new RequestMappingInfo(this.mappingName, patternsCondition,
					new RequestMethodsRequestCondition(this.methods),
					new ParamsRequestCondition(this.params),
					new HeadersRequestCondition(this.headers),
					new ConsumesRequestCondition(this.consumes, this.headers),
					new ProducesRequestCondition(this.produces, this.headers, manager),
					this.customCondition);
		}		

	public static Method selectInvocableMethod(Method method, @Nullable Class<?> targetType) {
		if (targetType == null) {
			return method;
		}
		Method methodToUse = MethodIntrospector.selectInvocableMethod(method, targetType);
		#得到的方法是私有的,对象,并且是springproxy类的子类
		if (Modifier.isPrivate(methodToUse.getModifiers()) && !Modifier.isStatic(methodToUse.getModifiers()) &&
				SpringProxy.class.isAssignableFrom(targetType)) {
			throw new IllegalStateException(String.format(
					"Need to invoke method '%s' found on proxy for target class '%s' but cannot " +
					"be delegated to target bean. Switch its visibility to package or protected.",
					method.getName(), method.getDeclaringClass().getSimpleName()));
		}
		return methodToUse;
	}

#得到该方法声明的信息
	public static Method selectInvocableMethod(Method method, Class<?> targetType) {
	#如果声明该方法的类是targetType的父类,接口类,返回该方法
		if (method.getDeclaringClass().isAssignableFrom(targetType)) {
			return method;
		}
		try {
			String methodName = method.getName();
			Class<?>[] parameterTypes = method.getParameterTypes();
			#遍历该类的所有接口,根据方法名和参数类型从这些接口查询声明该方法的接口
			for (Class<?> ifc : targetType.getInterfaces()) {
				try {
					return ifc.getMethod(methodName, parameterTypes);
				}
				catch (NoSuchMethodException ex) {
					// Alright, not on this interface then...
				}
			}
			// A final desperate attempt on the proxy class itself...
			return targetType.getMethod(methodName, parameterTypes);
		}
		catch (NoSuchMethodException ex) {
			throw new IllegalStateException(String.format(
					"Need to invoke method '%s' declared on target class '%s', " +
					"but not found in any interface(s) of the exposed proxy type. " +
					"Either pull the method up to an interface or switch to CGLIB " +
					"proxies by enforcing proxy-target-class mode in your configuration.",
					method.getName(), method.getDeclaringClass().getSimpleName()));
		}
	}

#org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#registerHandlerMethod
	@Override
	protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
	#调用父类的方法
		super.registerHandlerMethod(handler, method, mapping);
		updateConsumesCondition(mapping, method);
	}

#org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#registerHandlerMethod
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
#通过mappingRegistry将获取到的mapping,handler和method
#this代表RequestMappingHandlerMapping,mapping代表RequestMappingInfo,method代表反射调用的方法
		this.mappingRegistry.register(mapping, handler, method);
	}
#org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry#register
		public void register(T mapping, Object handler, Method method) {
			// Assert that the handler method is not a suspending one.
			#检测是否是KotlinType
			if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {
				Class<?>[] parameterTypes = method.getParameterTypes();
				if ((parameterTypes.length > 0) && "kotlin.coroutines.Continuation".equals(parameterTypes[parameterTypes.length - 1].getName())) {
					throw new IllegalStateException("Unsupported suspending handler method detected: " + method);
				}
			}
			#读写锁中的写锁进行锁定,mappingRegistry需要支持并发方法,所以要进行上锁
			this.readWriteLock.writeLock().lock();
			try {
			#创建handlerMethod
				HandlerMethod handlerMethod = createHandlerMethod(handler, method);
            #验证唯一性,一个requestMapingInfo对应一个handlerMethod,如果存在则抛出异常
				validateMethodMapping(handlerMethod, mapping);
                #this代表RequestMappingHandlerMapping.MappingRegistry,map中保存requestMappingINfo和methodHandler之间的关系
				this.mappingLookup.put(mapping, handlerMethod);
				#通过mapping中的PatternsRequestCondition的pattern查询满足的url
				List<String> directUrls = getDirectUrls(mapping);
				for (String url : directUrls) {
				# 用于保存url和对应的requestMappingInfo之间的关系
					this.urlLookup.add(url, mapping);
				}

				String name = null;
				if (getNamingStrategy() != null) {
				#使用hanlder中的大写字母#方法名称拼接而成
					name = getNamingStrategy().getName(handlerMethod, mapping);
				#保存name和handlermethod之间的关系
					addMappingName(name, handlerMethod);
				}
				#返回空的corsConfiguration
				CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
				#如果不为空,建立该方法和corsconfig之间的关系,保存到corsLookup中
				if (corsConfig != null) {
					this.corsLookup.put(handlerMethod, corsConfig);
				}
#registry中保存了mapping和MappingRegistration之间的关系,MappingRegistration保存了所有的映射结果信息
				this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name));
			}
			finally {
			#释放读锁
				this.readWriteLock.writeLock().unlock();
			}
		}

	protected HandlerMethod createHandlerMethod(Object handler, Method method) {
	#如果handler是名称
		if (handler instanceof String) {
		#通过名称创建HandlerMethod
			return new HandlerMethod((String) handler,
					obtainApplicationContext().getAutowireCapableBeanFactory(), method);
		}
		#通过handler和method创建handlerMethod()名副其实)
		return new HandlerMethod(handler, method);
	}

	public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) {
		Assert.hasText(beanName, "Bean name is required");
		Assert.notNull(beanFactory, "BeanFactory is required");
		Assert.notNull(method, "Method is required");
		this.bean = beanName;
		this.beanFactory = beanFactory;
		#通过传入的handler名称获得handler类型
		Class<?> beanType = beanFactory.getType(beanName);
		if (beanType == null) {
			throw new IllegalStateException("Cannot resolve bean type for bean with name '" + beanName + "'");
		}
		#用于在cglib的情况下获得代理的类
		this.beanType = ClassUtils.getUserClass(beanType);
		this.method = method;
		#获得桥接方法
		this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
		#初始化bridgedMethod 中的参数对象
		this.parameters = initMethodParameters();
		evaluateResponseStatus();
		#descriptionw为类名#方法名
		this.description = initDescription(this.beanType, this.method);
	}

	private MethodParameter[] initMethodParameters() {
	#获得桥接方法的参数的个数
		int count = this.bridgedMethod.getParameterCount();
		#创建长度为count的数组
		MethodParameter[] result = new MethodParameter[count];
		for (int i = 0; i < count; i++) {
			result[i] = new HandlerMethodParameter(i);
		}
		return result;
	}
#创建bridgedMethod的第index个参数的HandlerMethodParameter
public HandlerMethodParameter(int index) {
			super(HandlerMethod.this.bridgedMethod, index);
		}

	private void evaluateResponseStatus() {
	#得到该方法的@ResponseStatus欣姐
		ResponseStatus annotation = getMethodAnnotation(ResponseStatus.class);
		#如果该方法上没有该注解
		if (annotation == null) {
		
			annotation = AnnotatedElementUtils.findMergedAnnotation(getBeanType(), ResponseStatus.class);
		}
		#获得注解信息
		if (annotation != null) {
		#将注解中的信息保存到handlerMethod中的responseStatus,responseStatusReason 变量中
			this.responseStatus = annotation.code();
			this.responseStatusReason = annotation.reason();
		}
	}
#发现该method对象中的某个注解类型的注解
	public <A extends Annotation> A getMethodAnnotation(Class<A> annotationType) {
		return AnnotatedElementUtils.findMergedAnnotation(this.method, annotationType);
	}
#org.springframework.core.annotation.AnnotatedElementUtils#findMergedAnnotation
	public static <A extends Annotation> A findMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
		// Shortcut: directly present on the element, with no merging needed?
		#AnnotationFilter PLAIN = packages("java.lang", "org.springframework.lang")
		#判断annotationType是否符合该AnnotationFilter或者是java自带的,
		if (AnnotationFilter.PLAIN.matches(annotationType) ||
				AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
				#获得该元素声明类型为annotationType的注解信息
			return element.getDeclaredAnnotation(annotationType);
		}
		// Exhaustive retrieval of merged annotations...
		return findAnnotations(element)
				.get(annotationType, null, MergedAnnotationSelectors.firstDirectlyDeclared())
				.synthesize(MergedAnnotation::isPresent).orElse(null);
	}


#org.springframework.core.annotation.AnnotationsScanner#hasPlainJavaAnnotationsOnly(java.lang.Object)
static boolean hasPlainJavaAnnotationsOnly(@Nullable Object annotatedElement) {
#如果annotatedElement 为class对象
		if (annotatedElement instanceof Class) {
		#该注解是否是order类型或者是java自带的
			return hasPlainJavaAnnotationsOnly((Class<?>) annotatedElement);
		}
		#该注解元素是field,方法或者构造函数的实例
		else if (annotatedElement instanceof Member) {
		#判断其生命类是否是order类型或者java自带的
			return hasPlainJavaAnnotationsOnly(((Member) annotatedElement).getDeclaringClass());
		}
		else {
			return false;
		}
	}
#判断该type是否是java包下,或者是order类型
	static boolean hasPlainJavaAnnotationsOnly(Class<?> type) {
		return (type.getName().startsWith("java.") || type == Ordered.class);
	}
#进行注解合并
	private static MergedAnnotations findAnnotations(AnnotatedElement element) {
		return MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY, RepeatableContainers.none());
	}

#org.springframework.core.annotation.AnnotatedElementUtils#findMergedAnnotation
#根据annotationType,predicate和selector获得合并后的注解
	@Override
	public <A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType,
			@Nullable Predicate<? super MergedAnnotation<A>> predicate,
			@Nullable MergedAnnotationSelector<A> selector) {

		MergedAnnotation<A> result = find(annotationType, predicate, selector);
		return (result != null ? result : MergedAnnotation.missing());
	}

	private static String initDescription(Class<?> beanType, Method method) {
		StringJoiner joiner = new StringJoiner(", ", "(", ")");
		for (Class<?> paramType : method.getParameterTypes()) {
			joiner.add(paramType.getSimpleName());
		}
		#通过beanType名和方法名获的描述信息
		return beanType.getName() + "#" + method.getName() + joiner.toString();
	}

		private void validateMethodMapping(HandlerMethod handlerMethod, T mapping) {
			// Assert that the supplied mapping is unique.
			#Map<T, HandlerMethod> mappingLookup = new LinkedHashMap<>();
			#通过mapping查询相应的handlerMethod
			#为啥mapping不是string?
			#检测mapping的handlerMethod是否存在 
			HandlerMethod existingHandlerMethod = this.mappingLookup.get(mapping);
			#如果从map中取到的handlerMethod和即将需要和mapping建立关系的handlerMapping不相等,抛出Ambiguous mapping异常
			if (existingHandlerMethod != null && !existingHandlerMethod.equals(handlerMethod)) {
				throw new IllegalStateException(
						"Ambiguous mapping. Cannot map '" + handlerMethod.getBean() + "' method \n" +
						handlerMethod + "\nto " + mapping + ": There is already '" +
						existingHandlerMethod.getBean() + "' bean method\n" + existingHandlerMethod + " mapped.");
			}
		}

	private List<String> getDirectUrls(T mapping) {
			List<String> urls = new ArrayList<>(1);
			#getMappingPathPatterns为抽象方法,具体实现在RequestMappingInfoHandlerMapping
			for (String path : getMappingPathPatterns(mapping)) {
				if (!getPathMatcher().isPattern(path)) {
				#如果从mapping中获得的path不匹配AbstractHandlerMapping中定义的pathMatcher,则将该path添加到urls集合
					urls.add(path);
				}
			}
			return urls;
		}
#org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping#getMappingPathPatterns
	protected Set<String> getMappingPathPatterns(RequestMappingInfo info) {
	#获得该info中的path集合
		return info.getPatternsCondition().getPatterns();
	}

#org.springframework.web.servlet.handler.AbstractHandlerMapping#getPathMatcher
	public PathMatcher getPathMatcher() {
	#返回给antpathmatcher
		return this.pathMatcher;
	}
	#返回配置的命名策略
	public HandlerMethodMappingNamingStrategy<T> getNamingStrategy() {
		return this.namingStrategy;
	}
#命名策略
	@Override
	public String getName(HandlerMethod handlerMethod, RequestMappingInfo mapping) {
	#如果mapping中的name存在,是用该name
		if (mapping.getName() != null) {
			return mapping.getName();
		}
		StringBuilder sb = new StringBuilder();
		#得到handler的类名(不包含包名)
		String simpleTypeName = handlerMethod.getBeanType().getSimpleName();
		for (int i = 0; i < simpleTypeName.length(); i++) {
		#挑选出类名中的大写字母
			if (Character.isUpperCase(simpleTypeName.charAt(i))) {
				sb.append(simpleTypeName.charAt(i));
			}
		}
		#public static final String SEPARATOR = "#"
		#和方法名进行拼接
		sb.append(SEPARATOR).append(handlerMethod.getMethod().getName());
		return sb.toString();
	}

	private void addMappingName(String name, HandlerMethod handlerMethod) {
	#根据该name查询所有的handlerMethod
			List<HandlerMethod> oldList = this.nameLookup.get(name);
			if (oldList == null) {
			#为空返回空集合
				oldList = Collections.emptyList();
			}
	#遍历根据name得到的list,如果遍历到的current和handlerMethod相等,返回
			for (HandlerMethod current : oldList) {
				if (handlerMethod.equals(current)) {
					return;
				}
			}
	#新建空的list
			List<HandlerMethod> newList = new ArrayList<>(oldList.size() + 1);
			#将所有的oldlist放到新建的list
			newList.addAll(oldList);
			#将handlerMethod加入到newlist
			newList.add(handlerMethod);
			#缓存到map中
			this.nameLookup.put(name, newList);
		}
		#返回为空
	protected CorsConfiguration initCorsConfiguration(Object handler, Method method, T mapping) {
		return null;
	}

	public MappingRegistration(T mapping, HandlerMethod handlerMethod,
				@Nullable List<String> directUrls, @Nullable String mappingName) {
#将mapping和handlerMethod,directUrls和mappingName关联到MappingRegistration
			Assert.notNull(mapping, "Mapping must not be null");
			Assert.notNull(handlerMethod, "HandlerMethod must not be null");
			this.mapping = mapping;
			this.handlerMethod = handlerMethod;
			this.directUrls = (directUrls != null ? directUrls : Collections.emptyList());
			this.mappingName = mappingName;
		}


	private void updateConsumesCondition(RequestMappingInfo info, Method method) {
	#返回info中的ConsumesCondition对象
		ConsumesRequestCondition condition = info.getConsumesCondition();
		if (!condition.isEmpty()) {
		#在condition不为空的情况下,遍历method的参数
			for (Parameter parameter : method.getParameters()) {
		#从parameter中的所有注解和元注解创建MergedAnnotation实例
		#得到@RequestBody注解或者元注解
				MergedAnnotation<RequestBody> annot = MergedAnnotations.from(parameter).get(RequestBody.class);
		#如果参数中被@RequestBody修饰 
				if (annot.isPresent()) {
		#设置注解中的require参数设置是否需要body
					condition.setBodyRequired(annot.getBoolean("required"));
					break;
				}
			}
		}
	}
#org.springframework.core.annotation.MergedAnnotations#from(java.lang.reflect.AnnotatedElement)
	static MergedAnnotations from(AnnotatedElement element) {
		return from(element, SearchStrategy.DIRECT);
	}
	static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy) {
		return from(element, searchStrategy, RepeatableContainers.standardRepeatables());
	}

public static RepeatableContainers standardRepeatables() {
		return StandardRepeatableContainers.INSTANCE;
	}
	
	#org.springframework.core.annotation.TypeMappedAnnotations#from(java.lang.reflect.AnnotatedElement, org.springframework.core.annotation.MergedAnnotations.SearchStrategy, org.springframework.core.annotation.RepeatableContainers, org.springframework.core.annotation.AnnotationFilter)
	static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy,
			RepeatableContainers repeatableContainers) {

		return TypeMappedAnnotations.from(element, searchStrategy, repeatableContainers, AnnotationFilter.PLAIN);
	}
static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy,
			RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter) {
			#ruguo meiyou dedao xvyao jinyibu chulide 
		if (AnnotationsScanner.isKnownEmpty(element, searchStrategy)) {
			return NONE;
		}
		return new TypeMappedAnnotations(element, searchStrategy, repeatableContainers, annotationFilter);
	}

#根据搜索策略判断source是否存在进一步处理的注解
	static boolean isKnownEmpty(AnnotatedElement source, SearchStrategy searchStrategy) {
	#如果只有java注解的
		if (hasPlainJavaAnnotationsOnly(source)) {
			return true;
		}
		#如果搜索策略为DIRECT 或者没有继承结构
		if (searchStrategy == SearchStrategy.DIRECT || isWithoutHierarchy(source, searchStrategy)) {
		#如果该方法为桥接方法,返回false
			if (source instanceof Method && ((Method) source).isBridge()) {
				return false;
			}
			return getDeclaredAnnotations(source, false).length == 0;
		}
		return false;
	}
	#在该SearchStrategy下的AnnotatedElement 没有
   private static boolean isWithoutHierarchy(AnnotatedElement source, SearchStrategy searchStrategy) {
   #为object返回true
		if (source == Object.class) {
			return true;
		}
		#为class对象
		if (source instanceof Class) {
			Class<?> sourceClass = (Class<?>) source;
			#既没有父类,也没有接口,返回true
			boolean noSuperTypes = (sourceClass.getSuperclass() == Object.class &&
					sourceClass.getInterfaces().length == 0);
					
			return (searchStrategy == SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES ? noSuperTypes &&
					sourceClass.getEnclosingClass() == null : noSuperTypes);
		}
		if (source instanceof Method) {
			Method sourceMethod = (Method) source;
			#判断source是否是私有,该方法的声明类是否没有继承结构
			return (Modifier.isPrivate(sourceMethod.getModifiers()) ||
					isWithoutHierarchy(sourceMethod.getDeclaringClass(), searchStrategy));
		}
		return true;
	}
#org.springframework.core.annotation.AnnotationsScanner#getDeclaredAnnotations(java.lang.reflect.AnnotatedElement, boolean)
static Annotation[] getDeclaredAnnotations(AnnotatedElement source, boolean defensive) {
		boolean cached = false;
		###private static final Map<AnnotatedElement, Annotation[]> declaredAnnotationCache =
			new ConcurrentReferenceHashMap<>(256);
			#从cache中取到source的注解	
		Annotation[] annotations = declaredAnnotationCache.get(source);
		#从cache中取到值,
		if (annotations != null) {
			cached = true;
		}
		else {
		#从source中获得声明的注解
			annotations = source.getDeclaredAnnotations();
			if (annotations.length != 0) {
				boolean allIgnored = true;
				for (int i = 0; i < annotations.length; i++) {
					Annotation annotation = annotations[i];
					#如果该注解可以忽略,或者该注解非法,
					if (isIgnorable(annotation.annotationType()) ||
							!AttributeMethods.forAnnotationType(annotation.annotationType()).isValid(annotation)) {
						annotations[i] = null;
					}
					else {
					#存在不和忽略的和合法的注解,将allIgnored 置为false
						allIgnored = false;
					}
				}
				#返回可以进一步处理的注解
				annotations = (allIgnored ? NO_ANNOTATIONS : annotations);
				if (source instanceof Class || source instanceof Member) {
				#保存source和注解之间的关系到map中
					declaredAnnotationCache.put(source, annotations);
					cached = true;
				}
			}
		}
		#如果不保护,注解长度为0,不缓存,直接返回注解
		if (!defensive || annotations.length == 0 || !cached) {
			return annotations;
		}
		#clone该注解
		return annotations.clone();
	}

#如果是java的注解,可以忽略
	private static boolean isIgnorable(Class<?> annotationType) {
		return AnnotationFilter.PLAIN.matches(annotationType);
	}
	
	boolean isValid(Annotation annotation) {
		assertAnnotation(annotation);
		for (int i = 0; i < size(); i++) {
			if (canThrowTypeNotPresentException(i)) {
				try {
				#通过反射调用,没有抛出异常则合法
					get(i).invoke(annotation);
				}
				catch (Throwable ex) {
					return false;
				}
			}
		}
		return true;
	}

	boolean canThrowTypeNotPresentException(int index) {
	#检索数组中index位置存储的值,该位置是否可以抛出TypeNotPresentException
		return this.canThrowTypeNotPresentException[index];
	}
#org.springframework.web.servlet.mvc.condition.ConsumesRequestCondition#setBodyRequired
	public void setBodyRequired(boolean bodyRequired) {
		this.bodyRequired = bodyRequired;
	}
	
	private <T> T getRequiredAttributeValue(String attributeName, Class<T> type) {
		T value = getAttributeValue(attributeName, type);
		if (value == null) {
			throw new NoSuchElementException("No attribute named '" + attributeName +
					"' present in merged annotation " + getType().getName());
		}
		return value;
	}
	
	protected <T> T getAttributeValue(String attributeName, Class<T> type) {
	#获得该attributeName在属性中attributeName数组的位置,可能为-1
		int attributeIndex = getAttributeIndex(attributeName, false);
		return (attributeIndex != -1 ? getValue(attributeIndex, type) : null);
	}

	private int getAttributeIndex(String attributeName, boolean required) {
		Assert.hasText(attributeName, "Attribute name must not be null");
		#如果该注解的属性中存在该attributeName,返回相应的index,否则返回-1
		int attributeIndex = (isFiltered(attributeName) ? -1 : this.mapping.getAttributes().indexOf(attributeName));
		if (attributeIndex == -1 && required) {
			throw new NoSuchElementException("No attribute named '" + attributeName +
					"' present in merged annotation " + getType().getName());
		}
		return attributeIndex;
	}

	private boolean isFiltered(String attributeName) {
	#如果存在attributeFilter 
		if (this.attributeFilter != null) {
		#该Predicate的test和attributeName进行比较
			return !this.attributeFilter.test(attributeName);
		}
		return false;
	}

	public Map<T, HandlerMethod> getHandlerMethods() {
	#获取读锁
	#为啥???
		this.mappingRegistry.acquireReadLock();
		try {
		#将获得的mappingLookup封装到一个只读map中
			return Collections.unmodifiableMap(this.mappingRegistry.getMappings());
		}
		finally {
		#释放读锁
			this.mappingRegistry.releaseReadLock();
		}
	}

#返回所有的mapping和handlerMethod
	public Map<T, HandlerMethod> getMappings() {
			return this.mappingLookup;
		}
	protected void handlerMethodsInitialized(Map<T, HandlerMethod> handlerMethods) {
		// Total includes detected mappings + explicit registrations via registerMapping
		int total = handlerMethods.size();
		if ((logger.isTraceEnabled() && total == 0) || (logger.isDebugEnabled() && total > 0) ) {
			logger.debug(total + " mappings in " + formatMappingName());
		}
	}

#提供了便捷的访问方法参数,参数类型,返回值,注解的类
public class HandlerMethod {

	/** Logger that is available to subclasses. */
	protected final Log logger = LogFactory.getLog(getClass());

	private final Object bean;

	@Nullable
	private final BeanFactory beanFactory;

	private final Class<?> beanType;

	private final Method method;

	private final Method bridgedMethod;

	private final MethodParameter[] parameters;

	@Nullable
	private HttpStatus responseStatus;

	@Nullable
	private String responseStatusReason;

	@Nullable
	private HandlerMethod resolvedFromHandlerMethod;

	@Nullable
	private volatile List<Annotation[][]> interfaceParameterAnnotations;

	private final String description;}

至此,分析完了RequestMappingHandlerMapping在初始化所作的工作,就是将url和method的对应,将关系保存在RequestMappingHandlerMapping的mappingRegistry的相关属性中。

#RequestMappingHandlerMapping的工作流程

如果发起一个http请求,

#org.springframework.web.servlet.DispatcherServlet#getHandler
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		if (this.handlerMappings != null) {
            #遍历注册到spring mvc容器中的HandlerMapping(RequestMappingHandlerMapping是该类的子类)
			for (HandlerMapping mapping : this.handlerMappings) {
             #调用handlerMapping中的getHandler接口
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
					return handler;
				}
			}
		}
		return null;
	}
#org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler
#此时会调用AbstractHandlerMapping的gethandler接口    
	public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    #getHandlerInternal为抽象接口,获得到最佳匹配的handlerMethod
		Object handler = getHandlerInternal(request);
		if (handler == null) {
			handler = getDefaultHandler();
		}
		if (handler == null) {
			return null;
		}
		// Bean name or resolved handler?
		if (handler instanceof String) {
			String handlerName = (String) handler;
			handler = obtainApplicationContext().getBean(handlerName);
		}
		#包含拦截器和handler
		HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

		if (logger.isTraceEnabled()) {
			logger.trace("Mapped to " + handler);
		}
		else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
			logger.debug("Mapped to " + executionChain.getHandler());
		}

		if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
			CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
			CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
			config = (config != null ? config.combine(handlerConfig) : handlerConfig);
			executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
		}

		return executionChain;
	}

#org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping#getHandlerInternal
    protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
		#String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes";
    	#	该属性可能在某些实现类中不支持,所以去掉
    	request.removeAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
		try {
			return super.getHandlerInternal(request);
		}
		finally {
			ProducesRequestCondition.clearMediaTypesAttribute(request);
		}
	}
#org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#getHandlerInternal
	protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
    #获取请求路径
		String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
		request.setAttribute(LOOKUP_PATH, lookupPath);
		this.mappingRegistry.acquireReadLock();
		try {
            #该处为url匹配handlerMethod的核心逻辑,调用AbstractHandlerMethodMapping中的方法
			HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
			return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
		}
		finally {
			this.mappingRegistry.releaseReadLock();
		}
	}
#org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#lookupHandlerMethod
	protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
		List<Match> matches = new ArrayList<>();
    #通过url查询RequestMappingInfo
        #通过url获得info        
		List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
		if (directPathMatches != null) {
            #先是通过路径获得info,然后通过info列表获得handlerMethod,
			addMatchingMappings(directPathMatches, matches, request);
		}
		if (matches.isEmpty()) {
			// No choice but to go through all mappings...
			#可能是由于通配符的问题没有匹配上
            addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
		}

		if (!matches.isEmpty()) {
            #假设第一个为最佳匹配的match
			Match bestMatch = matches.get(0);
			if (matches.size() > 1) {
                #使用request得到antpathcomparator
				Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
				matches.sort(comparator);
                #返回第一个值
				bestMatch = matches.get(0);
				if (logger.isTraceEnabled()) {
					logger.trace(matches.size() + " matching mappings: " + matches);
				}
                #如果是preflight,返回emptyHandler
				if (CorsUtils.isPreFlightRequest(request)) {
					return PREFLIGHT_AMBIGUOUS_MATCH;
				}
				Match secondBestMatch = matches.get(1);
                #如果最大值有两个相等的,会抛出Ambiguous handler methods异常
				if (comparator.compare(bestMatch, secondBestMatch) == 0) {              
					Method m1 = bestMatch.handlerMethod.getMethod();
					Method m2 = secondBestMatch.handlerMethod.getMethod();
					String uri = request.getRequestURI();
					throw new IllegalStateException(
							"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
				}
			}
            #String BEST_MATCHING_HANDLER_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingHandler",将匹配好的handlermethod放入到request的attribute中
			request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
            #抽象方法,给request设置相应的属性,比如pathvariable的解析值
			handleMatch(bestMatch.mapping, lookupPath, request);
			return bestMatch.handlerMethod;
		}
		else {
            #抛出方法不支持,比如HttpRequestMethodNotSupportedException,HttpMediaTypeNotSupportedException
			return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
		}
	}


	private void addMatchingMappings(Collection<T> mappings, List<Match> matches, HttpServletRequest request) {
		for (T mapping : mappings) {
            #通过mapping和request进行匹配,判断request是否满足info中的condition条件,不满足说明该info和request不匹配返回null,
                否则,返回该condition,然后通过所有的满足的conditon创建新的info对象返回
			T match = getMatchingMapping(mapping, request);
			if (match != null) {
                #通过requestMappingInfo获得相应的HandlerMethod
				matches.add(new Match(match, this.mappingRegistry.getMappings().get(mapping)));
			}
		}
	}
#org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping#getMatchingMapping
	protected RequestMappingInfo getMatchingMapping(RequestMappingInfo info, HttpServletRequest request) {
		return info.getMatchingCondition(request);
	}

#org.springframework.web.servlet.mvc.method.RequestMappingInfo#getMatchingCondition
public RequestMappingInfo getMatchingCondition(HttpServletRequest request) {
		RequestMethodsRequestCondition methods = this.methodsCondition.getMatchingCondition(request);
		if (methods == null) {
			return null;
		}
    #按照已经requestMappingInfo中的信息对request尽心匹配,匹配不上就返回
		ParamsRequestCondition params = this.paramsCondition.getMatchingCondition(request);
		if (params == null) {
			return null;
		}
		HeadersRequestCondition headers = this.headersCondition.getMatchingCondition(request);
		if (headers == null) {
			return null;
		}
		ConsumesRequestCondition consumes = this.consumesCondition.getMatchingCondition(request);
		if (consumes == null) {
			return null;
		}
		ProducesRequestCondition produces = this.producesCondition.getMatchingCondition(request);
		if (produces == null) {
			return null;
		}
    #根据request中的path进行路径匹配,实现模糊匹配
		PatternsRequestCondition patterns = this.patternsCondition.getMatchingCondition(request);
		if (patterns == null) {
			return null;
		}
		RequestConditionHolder custom = this.customConditionHolder.getMatchingCondition(request);
		if (custom == null) {
			return null;
		}

		return new RequestMappingInfo(this.name, patterns,
				methods, params, headers, consumes, produces, custom.getCondition());
	}

#org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition#getMatchingCondition
	public RequestMethodsRequestCondition getMatchingCondition(HttpServletRequest request) {
		if (CorsUtils.isPreFlightRequest(request)) {
			return matchPreFlight(request);
		}

		if (getMethods().isEmpty()) {
			if (RequestMethod.OPTIONS.name().equals(request.getMethod()) &&
					!DispatcherType.ERROR.equals(request.getDispatcherType())) {

				return null; // We handle OPTIONS transparently, so don't match if no explicit declarations
			}
			return this;
		}

		return matchRequestMethod(request.getMethod());
	}

#org.springframework.web.cors.CorsUtils#isPreFlightRequest
public static boolean isPreFlightRequest(HttpServletRequest request) {
    #public static final String ORIGIN = "Origin";
    #	public static final String ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method";
    #请求方法为OPTIONS,有origin和Access-Control-Request-Method请求头返回true
		return (HttpMethod.OPTIONS.matches(request.getMethod()) &&
				request.getHeader(HttpHeaders.ORIGIN) != null &&
				request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null);
	}

#如果是preflight请求,
	private RequestMethodsRequestCondition matchPreFlight(HttpServletRequest request) {
		if (getMethods().isEmpty()) {
			return this;
		}
		String expectedMethod = request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD);
		return matchRequestMethod(expectedMethod);
	}
#org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition#getMethods    
	public Set<RequestMethod> getMethods() {
		return this.methods;
	}
#org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition#matchRequestMethod
	private RequestMethodsRequestCondition matchRequestMethod(String httpMethodValue) {
		RequestMethod requestMethod;
		try {
			requestMethod = RequestMethod.valueOf(httpMethodValue);
			if (getMethods().contains(requestMethod)) {
                #private static final Map<String, RequestMethodsRequestCondition> requestMethodConditionCache
				return requestMethodConditionCache.get(httpMethodValue);
			}
			if (requestMethod.equals(RequestMethod.HEAD) && getMethods().contains(RequestMethod.GET)) {
                #将head也是按照get处理吗?
				return requestMethodConditionCache.get(HttpMethod.GET.name());
			}
		}
		catch (IllegalArgumentException ex) {
			// Custom request method
		}
		return null;
	}

#org.springframework.web.servlet.mvc.condition.PatternsRequestCondition#getMatchingCondition
	public PatternsRequestCondition getMatchingCondition(HttpServletRequest request) {
		if (this.patterns.isEmpty()) {
			return this;
		}
		String lookupPath = this.pathHelper.getLookupPathForRequest(request, HandlerMapping.LOOKUP_PATH);
		List<String> matches = getMatchingPatterns(lookupPath);
		return !matches.isEmpty() ? new PatternsRequestCondition(new LinkedHashSet<>(matches), this) : null;
	}
#org.springframework.web.util.UrlPathHelper#getLookupPathForRequest(javax.servlet.http.HttpServletRequest, java.lang.String)
	public String getLookupPathForRequest(HttpServletRequest request, @Nullable String lookupPathAttributeName) {
		if (lookupPathAttributeName != null) {
            #request中的属性含有key-value:org.springframework.web.servlet.HandlerMapping.lookupPath -> /count/reuse
			String result = (String) request.getAttribute(lookupPathAttributeName);
			if (result != null) {
				return result;
			}
		}
		return getLookupPathForRequest(request);
	}

#org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping#getMappingComparator
@Override
	protected Comparator<RequestMappingInfo> getMappingComparator(final HttpServletRequest request) {
		return (info1, info2) -> info1.compareTo(info2, request);
	}

#org.springframework.web.servlet.mvc.method.RequestMappingInfo#compareTo
    #实现接口方法org.springframework.web.servlet.mvc.condition.RequestCondition#compareTo
	public int compareTo(RequestMappingInfo other, HttpServletRequest request) {
		int result;
		// Automatic vs explicit HTTP HEAD mapping
		if (HttpMethod.HEAD.matches(request.getMethod())) {
			result = this.methodsCondition.compareTo(other.getMethodsCondition(), request);
			if (result != 0) {
				return result;
			}
		}
    #requestmapping定义中的模糊匹配问题
		result = this.patternsCondition.compareTo(other.getPatternsCondition(), request);
		if (result != 0) {
			return result;
		}
		result = this.paramsCondition.compareTo(other.getParamsCondition(), request);
		if (result != 0) {
			return result;
		}
		result = this.headersCondition.compareTo(other.getHeadersCondition(), request);
		if (result != 0) {
			return result;
		}
		result = this.consumesCondition.compareTo(other.getConsumesCondition(), request);
		if (result != 0) {
			return result;
		}
		result = this.producesCondition.compareTo(other.getProducesCondition(), request);
		if (result != 0) {
			return result;
		}
		// Implicit (no method) vs explicit HTTP method mappings
		result = this.methodsCondition.compareTo(other.getMethodsCondition(), request);
		if (result != 0) {
			return result;
		}
		result = this.customConditionHolder.compareTo(other.customConditionHolder, request);
		if (result != 0) {
			return result;
		}
		return 0;
	}

	#org.springframework.web.servlet.mvc.condition.PatternsRequestCondition#compareTo
	public int compareTo(PatternsRequestCondition other, HttpServletRequest request) {
		String lookupPath = this.pathHelper.getLookupPathForRequest(request, HandlerMapping.LOOKUP_PATH);
        #使用AntPatternComparator进行比较
		Comparator<String> patternComparator = this.pathMatcher.getPatternComparator(lookupPath);
		Iterator<String> iterator = this.patterns.iterator();
		Iterator<String> iteratorOther = other.patterns.iterator();
		while (iterator.hasNext() && iteratorOther.hasNext()) {
			int result = patternComparator.compare(iterator.next(), iteratorOther.next());
			if (result != 0) {
				return result;
			}
		}
		if (iterator.hasNext()) {
			return -1;
		}
		else if (iteratorOther.hasNext()) {
			return 1;
		}
		else {
			return 0;
		}
	}

#org.springframework.util.AntPathMatcher#getPatternComparator
public Comparator<String> getPatternComparator(String path) {
		return new AntPatternComparator(path);
	}

#org.springframework.util.AntPathMatcher.AntPatternComparator#compare中的compare逻辑,该类实现Comparator接口
	public int compare(String pattern1, String pattern2) {
			PatternInfo info1 = new PatternInfo(pattern1);
			PatternInfo info2 = new PatternInfo(pattern2);
			#isLeastSpecific当pattern为空或者匹配所有
			if (info1.isLeastSpecific() && info2.isLeastSpecific()) {
                #等于
				return 0;
			}
			else if (info1.isLeastSpecific()) {
                #大于
				return 1;
			}
			else if (info2.isLeastSpecific()) {
                #小于
				return -1;
			}#排序的结果是全部匹配排在最后面

			boolean pattern1EqualsPath = pattern1.equals(this.path);
			boolean pattern2EqualsPath = pattern2.equals(this.path);
			if (pattern1EqualsPath && pattern2EqualsPath) {
				return 0;
			}
			else if (pattern1EqualsPath) {
				return -1;
			}
			else if (pattern2EqualsPath) {
				return 1;
			}

			if (info1.isPrefixPattern() && info2.isPrefixPattern()) {
                #末尾以**结尾,路径长度更长的排在前面,路径更长意味更精确,如:/hello/ **和/hello/world/ **
				return info2.getLength() - info1.getLength();
			}
    #以下为末尾以**开始排在最后
			else if (info1.isPrefixPattern() && info2.getDoubleWildcards() == 0) {
				return 1;
			}
			else if (info2.isPrefixPattern() && info1.getDoubleWildcards() == 0) {
				return -1;
			}
	#更少数量的**,*,路径变量获胜,相等除外,比如:/hotels/abc*比/hotels/ *   totalCount=1*(路径变量个数)+1*(*个数)+2*(**个数)
			if (info1.getTotalCount() != info2.getTotalCount()) {
				return info1.getTotalCount() - info2.getTotalCount();
			}
	#通配符的数量一样,长度长的获胜,长度长意味更精确,长度相等的情况下除外,比如://hotels/*和/hotels/{user}
			if (info1.getLength() != info2.getLength()) {
				return info2.getLength() - info1.getLength();
			}
	#拥有更少的*获胜,*个数相同除外
			if (info1.getSingleWildcards() < info2.getSingleWildcards()) {
				return -1;
			}
			else if (info2.getSingleWildcards() < info1.getSingleWildcards()) {
				return 1;
			}
	#拥有更少的变量获胜
			if (info1.getUriVars() < info2.getUriVars()) {
				return -1;
			}
			else if (info2.getUriVars() < info1.getUriVars()) {
				return 1;
			}

			return 0;
		}

	
		private static class PatternInfo {

			@Nullable
			private final String pattern;

			private int uriVars;

			private int singleWildcards;

			private int doubleWildcards;

			private boolean catchAllPattern;

			private boolean prefixPattern;

			@Nullable
			private Integer length;

			public PatternInfo(@Nullable String pattern) {
				this.pattern = pattern;
				if (this.pattern != null) {
					initCounters();
                    #如果pattern是/ * *,表示匹配所有
					this.catchAllPattern = this.pattern.equals("/**");
                    #如果是结尾,则是prefixPattern
					this.prefixPattern = !this.catchAllPattern && this.pattern.endsWith("/**");
				}
				if (this.uriVars == 0) {
					this.length = (this.pattern != null ? this.pattern.length() : 0);
				}
			}

			protected void initCounters() {
				int pos = 0;
				if (this.pattern != null) {
					while (pos < this.pattern.length()) {
                        #用于处理pathvariable,统计数量
						if (this.pattern.charAt(pos) == '{') {
							this.uriVars++;
							pos++;
						}
						else if (this.pattern.charAt(pos) == '*') {
							if (pos + 1 < this.pattern.length() && this.pattern.charAt(pos + 1) == '*') {
                                #统计**的个数
								this.doubleWildcards++;
								pos += 2;
							}
							else if (pos > 0 && !this.pattern.substring(pos - 1).equals(".*")) {
                                #统计*的格式
								this.singleWildcards++;
								pos++;
							}
							else {
								pos++;
							}
						}
						else {
							pos++;
						}
					}
				}
			}

			public int getUriVars() {
				return this.uriVars;
			}

			public int getSingleWildcards() {
				return this.singleWildcards;
			}

			public int getDoubleWildcards() {
				return this.doubleWildcards;
			}
			#表示匹配所有
			public boolean isLeastSpecific() {
				return (this.pattern == null || this.catchAllPattern);
			}

			public boolean isPrefixPattern() {
				return this.prefixPattern;
			}
			#变量个数,单*个数,双*个数   ,这样是合理的,因为变量可以通过个数参与路径匹配
			public int getTotalCount() {
				return this.uriVars + this.singleWildcards + (2 * this.doubleWildcards);
			}

			/**
			 * Returns the length of the given pattern, where template variables are considered to be 1 long.
			 */
            #pathvariable代表1个长度
			public int getLength() {
				if (this.length == null) {
					this.length = (this.pattern != null ?
							VARIABLE_PATTERN.matcher(this.pattern).replaceAll("#").length() : 0);
				}
				return this.length;
			}
		}
	}

#org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping#handleMatch
	protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) {
    #将lookupPath写入request的attribute中
		super.handleMatch(info, lookupPath, request);

		String bestPattern;
		Map<String, String> uriVariables;

		Set<String> patterns = info.getPatternsCondition().getPatterns();
		if (patterns.isEmpty()) {
			bestPattern = lookupPath;
			uriVariables = Collections.emptyMap();
		}
		else {
			bestPattern = patterns.iterator().next();
            #此时提取路径中的变量,用于支持pathvariable,https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/AntPathMatcher.html,核心是:extractUriTemplateVariables方法
			uriVariables = getPathMatcher().extractUriTemplateVariables(bestPattern, lookupPath);
		}
#String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern";
		request.setAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE, bestPattern);
#支持MatrixVariables的写法
		if (isMatrixVariableContentAvailable()) {
			Map<String, MultiValueMap<String, String>> matrixVars = extractMatrixVariables(request, uriVariables);
			request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, matrixVars);
		}
#将提取处的值只用获得request中的进行解密,String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables"
		Map<String, String> decodedUriVariables = getUrlPathHelper().decodePathVariables(request, uriVariables);
		request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, decodedUriVariables);

		if (!info.getProducesCondition().getProducibleMediaTypes().isEmpty()) {
			Set<MediaType> mediaTypes = info.getProducesCondition().getProducibleMediaTypes();
			request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypes);
		}
	}

#org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#handleMatch
	protected void handleMatch(T mapping, String lookupPath, HttpServletRequest request) {
    #	String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping"
		request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, lookupPath);
	}

#org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping#handleNoMatch
	protected HandlerMethod handleNoMatch(
			Set<RequestMappingInfo> infos, String lookupPath, HttpServletRequest request) throws ServletException {

		PartialMatchHelper helper = new PartialMatchHelper(infos, request);
		if (helper.isEmpty()) {
			return null;
		}

		if (helper.hasMethodsMismatch()) {
			Set<String> methods = helper.getAllowedMethods();
			if (HttpMethod.OPTIONS.matches(request.getMethod())) {
				HttpOptionsHandler handler = new HttpOptionsHandler(methods);
				return new HandlerMethod(handler, HTTP_OPTIONS_HANDLE_METHOD);
			}
			throw new HttpRequestMethodNotSupportedException(request.getMethod(), methods);
		}

		if (helper.hasConsumesMismatch()) {
			Set<MediaType> mediaTypes = helper.getConsumableMediaTypes();
			MediaType contentType = null;
			if (StringUtils.hasLength(request.getContentType())) {
				try {
					contentType = MediaType.parseMediaType(request.getContentType());
				}
				catch (InvalidMediaTypeException ex) {
					throw new HttpMediaTypeNotSupportedException(ex.getMessage());
				}
			}
			throw new HttpMediaTypeNotSupportedException(contentType, new ArrayList<>(mediaTypes));
		}

		if (helper.hasProducesMismatch()) {
			Set<MediaType> mediaTypes = helper.getProducibleMediaTypes();
			throw new HttpMediaTypeNotAcceptableException(new ArrayList<>(mediaTypes));
		}

		if (helper.hasParamsMismatch()) {
			List<String[]> conditions = helper.getParamConditions();
			throw new UnsatisfiedServletRequestParameterException(conditions, request.getParameterMap());
		}

		return null;
	}


	public List<String> getMatchingPatterns(String lookupPath) {
		List<String> matches = null;
		for (String pattern : this.patterns) {
			String match = getMatchingPattern(pattern, lookupPath);
			if (match != null) {
				matches = matches != null ? matches : new ArrayList<>();
				matches.add(match);
			}
		}
		if (matches == null) {
			return Collections.emptyList();
		}
		if (matches.size() > 1) {
            #
			matches.sort(this.pathMatcher.getPatternComparator(lookupPath));
		}
		return matches;
	}


private String getMatchingPattern(String pattern, String lookupPath) {
		if (pattern.equals(lookupPath)) {
			return pattern;
		}
		if (this.useSuffixPatternMatch) {
			if (!this.fileExtensions.isEmpty() && lookupPath.indexOf('.') != -1) {
				for (String extension : this.fileExtensions) {
					if (this.pathMatcher.match(pattern + extension, lookupPath)) {
						return pattern + extension;
					}
				}
			}
			else {
				boolean hasSuffix = pattern.indexOf('.') != -1;
				if (!hasSuffix && this.pathMatcher.match(pattern + ".*", lookupPath)) {
					return pattern + ".*";
				}
			}
		}
		if (this.pathMatcher.match(pattern, lookupPath)) {
			return pattern;
		}
		if (this.useTrailingSlashMatch) {
			if (!pattern.endsWith("/") && this.pathMatcher.match(pattern + "/", lookupPath)) {
				return pattern + "/";
			}
		}
		return null;
	}


	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
				(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

		String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, LOOKUP_PATH);
        #将adaptedInterceptors加入拦截链
		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;
	}

总结:

controller中方法的解析流程

  • 在requestMappingHandler的afterPropertiesSet进行初始化设置和调用父类的afterPropertiesSet
  • 在父类AbstractHandlerMethodMapping的initHandlerMethods遍历spring mvc容器中的所有beanName,在processCandidateBean中根据 beanName判断该bean是否有@controller或者@requestMapping注解
  • 在detectHandlerMethods中根据beanName获得实际使用的类型(代理类),遍历该类型中所有的method,解析方法和类上的requestmapping注解信息,将其进行combine为新的RequestMappingInfo进行返回,该类通过各种conditon封装了requestmapping注解的信息
  • 在registerHandlerMethod方法中利用内部类mappingRegistry将info和handlerMethod保存到map中,完成方法的解析。

请求如何找到controller中的方法

  • 在DispatcherServlet的getHandler方法中遍历所有注册是handlerMapping,分别调用它们的getHandler方法,返回HandlerExecutionChain对象,该对象包含了对应处理请求的handlerMethod和处理该请求的拦截器

  • requestMappingHandler的getHandler方法会调用父类AbstractHandlerMethodMapping的getHandler

  • AbstractHandlerMethodMapping的lookupHandlerMethod,mappingRegistry对象根据url得到info列表,通过info中的condition选择可以处理该次请求的info,新建matcher对象。设置comparator然后对match进行排序,然后选出最匹配的返回

  • 涉及到对info进行排序,所以会调用RequestMappingInfo中的compareTo,该方法会调用各种condition的compareTo方法

  • 在patternsCondition实际调用了AntPatternComparator中的compare方法,定义了路径的匹配规则:可以匹配所有路径/**的优先级最低,后缀为/**的优先级次之,

  • org.springframework.util.AntPathMatcher#combine是如何合并的??
    根据spring介绍的combine的官方文档
    public String combine(String pattern1,
    String pattern2)
    主要用于将pattern1和pattern2进行合并

pattern1pattern1result
nullnull
/hotelsnull/hotels
null/hotels/hotels
/hotels/books/hotels/books
/hotelsbooks/hotels/books
/hotels/*/books/hotels/books
/hotels/**/bookings/hotels/**/bookings
/hotels{hotel}/hotels/{hotel}
/hotels/*{hotel}/hotels/{hotel}
/hotels/**{hotel}/hotels/**/{hotel}
  • org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#pathPrefixes有何作用?
  • org.springframework.beans.factory.config.EmbeddedValueResolver#resolveStringValue是如何工作的??
  • SpringProxy的作用??
  • KotlinType的作用??
  • ReentrantReadWriteLock如何使用
  • bridgeMethod的作用???
  • StringJoiner 的使用
  • Ambiguous mapping异常的过程
  • CorsConfiguration的作用原理
  • SearchStrategy原理
  • 数组对象.copy
  • LinkedHashMap 和hashmap的区别?LinkedHashSet和hashset?
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值