1. 目录 [TOC]
2. 说明 请求映射器主要是将url映射成应用中的执行对象,一般我们项目中是通过RequestMappingHandlerMapping
映射Controller
3. 依赖分析 4. 源码分析 从springmvc启动流程可以知道,springmvc请求映射是在initHandlerMappings()
中初始化的
4.1. initHandlerMappings() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 private void initHandlerMappings (ApplicationContext context) { this .handlerMappings = null ; if (this .detectAllHandlerMappings) { Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true , false ); if (!matchingBeans.isEmpty()) { this .handlerMappings = new ArrayList <>(matchingBeans.values()); AnnotationAwareOrderComparator.sort(this .handlerMappings); } } else { try { HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class); this .handlerMappings = Collections.singletonList(hm); } catch (NoSuchBeanDefinitionException ex) { } } if (this .handlerMappings == null ) { this .handlerMappings = getDefaultStrategies(context, HandlerMapping.class); if (logger.isTraceEnabled()) { logger.trace("No HandlerMappings declared for servlet '" + getServletName() + "': using default strategies from DispatcherServlet.properties" ); } } }
静态加载默认处理器
1 2 3 4 5 6 7 8 9 10 static { try { ClassPathResource resource = new ClassPathResource (DEFAULT_STRATEGIES_PATH, DispatcherServlet.class); defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } catch (IOException ex) { throw new IllegalStateException ("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage()); } }
4.2. 加载HandlerMapping 至容器中 前面启动流程我们已经讲了许多默认的bean的加载,这里再回顾一下RequestMappingHandlerMapping
的加载
在初始化mvc上下问的时候解析加载beanDefinition
的时候,spring在DefaultBeanDefinitionDocumentReader
解析自定义节点的时候,会通过BeanDefinitionParserDelegate
加载MvcNamespaceHandler
作为NamespaceHandlerSupport
解析xml节点。NamespaceHandlerSupport
配置的替换规则是在spring-mvc包下的META-INF/spring.handlers
中(具体spring的beanDifinition加载中有解析), 我们来看MvcNamespaceHandler
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Override public void init () { registerBeanDefinitionParser("annotation-driven" , new AnnotationDrivenBeanDefinitionParser ()); registerBeanDefinitionParser("default-servlet-handler" , new DefaultServletHandlerBeanDefinitionParser ()); registerBeanDefinitionParser("interceptors" , new InterceptorsBeanDefinitionParser ()); registerBeanDefinitionParser("resources" , new ResourcesBeanDefinitionParser ()); registerBeanDefinitionParser("view-controller" , new ViewControllerBeanDefinitionParser ()); registerBeanDefinitionParser("redirect-view-controller" , new ViewControllerBeanDefinitionParser ()); registerBeanDefinitionParser("status-controller" , new ViewControllerBeanDefinitionParser ()); registerBeanDefinitionParser("view-resolvers" , new ViewResolversBeanDefinitionParser ()); registerBeanDefinitionParser("tiles-configurer" , new TilesConfigurerBeanDefinitionParser ()); registerBeanDefinitionParser("freemarker-configurer" , new FreeMarkerConfigurerBeanDefinitionParser ()); registerBeanDefinitionParser("groovy-configurer" , new GroovyMarkupConfigurerBeanDefinitionParser ()); registerBeanDefinitionParser("script-template-configurer" , new ScriptTemplateConfigurerBeanDefinitionParser ()); registerBeanDefinitionParser("cors" , new CorsBeanDefinitionParser ()); }
初始化的时候默认加了一系列的BeanDefinitionParser
解析器,其中就包括了AnnotationDrivenBeanDefinitionParser
,这个Parser在执行解析的时候会将RequestMappingHandlerMapping
注册到beanDifinitionMap
中,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 public BeanDefinition parse (Element element, ParserContext context) { Object source = context.extractSource(element); XmlReaderContext readerContext = context.getReaderContext(); CompositeComponentDefinition compDefinition = new CompositeComponentDefinition (element.getTagName(), source); context.pushContainingComponent(compDefinition); RuntimeBeanReference contentNegotiationManager = getContentNegotiationManager(element, source, context); RootBeanDefinition handlerMappingDef = new RootBeanDefinition (RequestMappingHandlerMapping.class); handlerMappingDef.setSource(source); handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); handlerMappingDef.getPropertyValues().add("order" , 0 ); handlerMappingDef.getPropertyValues().add("contentNegotiationManager" , contentNegotiationManager); if (element.hasAttribute("enable-matrix-variables" )) { Boolean enableMatrixVariables = Boolean.valueOf(element.getAttribute("enable-matrix-variables" )); handlerMappingDef.getPropertyValues().add("removeSemicolonContent" , !enableMatrixVariables); } configurePathMatchingProperties(handlerMappingDef, element, context); readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef); RootBeanDefinition handlerAdapterDef = new RootBeanDefinition (RequestMappingHandlerAdapter.class); handlerAdapterDef.setSource(source); handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); handlerAdapterDef.getPropertyValues().add("contentNegotiationManager" , contentNegotiationManager); handlerAdapterDef.getPropertyValues().add("webBindingInitializer" , bindingDef); handlerAdapterDef.getPropertyValues().add("messageConverters" , messageConverters); addRequestBodyAdvice(handlerAdapterDef); addResponseBodyAdvice(handlerAdapterDef); if (element.hasAttribute("ignore-default-model-on-redirect" )) { Boolean ignoreDefaultModel = Boolean.valueOf(element.getAttribute("ignore-default-model-on-redirect" )); handlerAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect" , ignoreDefaultModel); } if (argumentResolvers != null ) { handlerAdapterDef.getPropertyValues().add("customArgumentResolvers" , argumentResolvers); } if (returnValueHandlers != null ) { handlerAdapterDef.getPropertyValues().add("customReturnValueHandlers" , returnValueHandlers); } if (asyncTimeout != null ) { handlerAdapterDef.getPropertyValues().add("asyncRequestTimeout" , asyncTimeout); } if (asyncExecutor != null ) { handlerAdapterDef.getPropertyValues().add("taskExecutor" , asyncExecutor); } handlerAdapterDef.getPropertyValues().add("callableInterceptors" , callableInterceptors); handlerAdapterDef.getPropertyValues().add("deferredResultInterceptors" , deferredResultInterceptors); readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef); context.registerComponent(new BeanComponentDefinition (handlerMappingDef, HANDLER_MAPPING_BEAN_NAME)); context.registerComponent(new BeanComponentDefinition (handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME)); MvcNamespaceUtils.registerDefaultComponents(context, source); context.popAndRegisterContainingComponent(); return null ; }
5. 总结 6. 注意事项