Author: HuiFer
源码阅读仓库: SourceHot-spring
源码路径:
org.springframework.jms.annotation.EnableJms
类全路径
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry
基本属性
classMappingRegistry { /** * key:mapping * value: mapping registration */privatefinalMap<T, MappingRegistration<T>> registry = newHashMap<>(); /** * key: mapping * value: handlerMethod */privatefinalMap<T, HandlerMethod> mappingLookup = newLinkedHashMap<>(); /** * key: url * value: list mapping */privatefinalMultiValueMap<String, T> urlLookup = newLinkedMultiValueMap<>(); /** * key: name * value: handler method */privatefinalMap<String, List<HandlerMethod>> nameLookup = newConcurrentHashMap<>(); /** * key:handler method * value: 跨域配置 */privatefinalMap<HandlerMethod, CorsConfiguration> corsLookup = newConcurrentHashMap<>(); /** * 读写锁 */privatefinalReentrantReadWriteLockreadWriteLock = newReentrantReadWriteLock(); }
写一个简单的 controller 来进行解析
@RestController@RequestMapping("/demo") publicclassDemoController { @GetMapping("/do") publicObjectgo() { return"fff"; } }
前置链路追踪
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#registerHandlerMethod
protectedvoidregisterHandlerMethod(Objecthandler, Methodmethod, RequestMappingInfomapping) { super.registerHandlerMethod(handler, method, mapping); this.updateConsumesCondition(mapping, method); }
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#registerHandlerMethod
protectedvoidregisterHandlerMethod(Objecthandler, Methodmethod, Tmapping) { this.mappingRegistry.register(mapping, handler, method); }
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry#register
本文重点的方法
先将对象截图出来方便后续理解
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#createHandlerMethod
protectedHandlerMethodcreateHandlerMethod(Objecthandler, Methodmethod) { // 是否是字符串if (handlerinstanceofString) { // 创建对象returnnewHandlerMethod((String) handler, obtainApplicationContext().getAutowireCapableBeanFactory(), method); } returnnewHandlerMethod(handler, method); }
HandlerMethod 构造函数
publicHandlerMethod(StringbeanName, BeanFactorybeanFactory, Methodmethod){} publicHandlerMethod(Objectbean, Methodmethod) {}
- 成员变量
publicclassHandlerMethod { /** Logger that is available to subclasses. */protectedfinalLoglogger = LogFactory.getLog(getClass()); /** * beanName 或者 bean 实例 */privatefinalObjectbean; /** * 上下文 */@NullableprivatefinalBeanFactorybeanFactory; /** * bean 类型 */privatefinalClass<?> beanType; /** * 处理方法 */privatefinalMethodmethod; privatefinalMethodbridgedMethod; /** * 方法参数 */privatefinalMethodParameter[] parameters; }
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry#validateMethodMapping
HandlerMethod 进行验证
privatevoidvalidateMethodMapping(HandlerMethodhandlerMethod, Tmapping) { // Assert that the supplied mapping is unique.// 从缓存中获取HandlerMethodexistingHandlerMethod = this.mappingLookup.get(mapping); // 是否为空 , 是否相同if (existingHandlerMethod != null && !existingHandlerMethod.equals(handlerMethod)) { thrownewIllegalStateException( "Ambiguous mapping. Cannot map '" + handlerMethod.getBean() + "' method \n" + handlerMethod + "\nto " + mapping + ": There is already '" + existingHandlerMethod.getBean() + "' bean method\n" + existingHandlerMethod + " mapped."); } }
找到 mapping 匹配的 url
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry#getDirectUrls
privateList<String> getDirectUrls(Tmapping) { List<String> urls = newArrayList<>(1); // mapping.getPatternsCondition().getPatterns()for (Stringpath : getMappingPathPatterns(mapping)) { // 是否匹配if (!getPathMatcher().isPattern(path)) { urls.add(path); } } returnurls; }
Stringname = null; if (getNamingStrategy() != null) { // 获取名字// 类名#方法名name = getNamingStrategy().getName(handlerMethod, mapping); // 设置 handlerMethod + name 的关系addMappingName(name, handlerMethod); }
org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMethodMappingNamingStrategy#getName
@OverridepublicStringgetName(HandlerMethodhandlerMethod, RequestMappingInfomapping) { if (mapping.getName() != null) { returnmapping.getName(); } StringBuildersb = newStringBuilder(); // 短类名StringsimpleTypeName = handlerMethod.getBeanType().getSimpleName(); for (inti = 0; i < simpleTypeName.length(); i++) { if (Character.isUpperCase(simpleTypeName.charAt(i))) { sb.append(simpleTypeName.charAt(i)); } } // 组装名称// 类名+#+方法名称sb.append(SEPARATOR).append(handlerMethod.getMethod().getName()); returnsb.toString(); }
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#initCorsConfiguration
@OverrideprotectedCorsConfigurationinitCorsConfiguration(Objecthandler, Methodmethod, RequestMappingInfomappingInfo) { // 创建 handlerMethodHandlerMethodhandlerMethod = createHandlerMethod(handler, method); // 获取 beanTypeClass<?> beanType = handlerMethod.getBeanType(); // 获取跨域注解 CrossOriginCrossOrigintypeAnnotation = AnnotatedElementUtils.findMergedAnnotation(beanType, CrossOrigin.class); CrossOriginmethodAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, CrossOrigin.class); if (typeAnnotation == null && methodAnnotation == null) { returnnull; } // 跨域信息配置CorsConfigurationconfig = newCorsConfiguration(); // 更新跨域配置updateCorsConfig(config, typeAnnotation); updateCorsConfig(config, methodAnnotation); if (CollectionUtils.isEmpty(config.getAllowedMethods())) { // 跨域配置赋给方法for (RequestMethodallowedMethod : mappingInfo.getMethodsCondition().getMethods()) { config.addAllowedMethod(allowedMethod.name()); } } // 应用跨域returnconfig.applyPermitDefaultValues(); }
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry#unregister
移除 mapping 信息
执行 map , list 相关的移除方法.
publicvoidunregister(Tmapping) { this.readWriteLock.writeLock().lock(); try { MappingRegistration<T> definition = this.registry.remove(mapping); if (definition == null) { return; } this.mappingLookup.remove(definition.getMapping()); for (Stringurl : definition.getDirectUrls()) { List<T> list = this.urlLookup.get(url); if (list != null) { list.remove(definition.getMapping()); if (list.isEmpty()) { this.urlLookup.remove(url); } } } removeMappingName(definition); this.corsLookup.remove(definition.getHandlerMethod()); } finally { this.readWriteLock.writeLock().unlock(); } }