SpringMvc有四種HandlerMapping:BeanNameUrlHandlerMapping ,SimpleUrlHandlerMapping,ControllerClassNameHandlerMapping ,DefaultAnnotationHandlerMapping。java
1. BeanNameUrlHandlerMapping (默認)根據controller的name名稱來映射尋找controller,開啓該映射:默認是開啓的web
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean> <bean id="helloController" name="/hello1.do" class="com.controller.HelloController"></bean> http://localhost:5080/springmvc/hello1.do
2.SimpleUrlHandlerMapping 根據URL來映射尋找controller, 開啓該映射:spring
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/hello2.do">HelloController</prop> </props> </property> </bean> http://localhost:5080/springmvc/hello2.do
3.ControllerClassNameHandlerMapping 根據controller的類名來映射尋找controller:mvc
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"></bean>
4. DefaultAnnotationHandlerMapping 使用註解來映射尋找controllerapp
<!--開啓springMVC註解 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>
使用java代碼配置的方式:this
/** * 將請求(/hessianremote.hessianservice)映射到hessianExporterService服務上 * @return */ @Bean public HandlerMapping hessianMapping() { SimpleUrlHandlerMapping mapping=new SimpleUrlHandlerMapping(); Properties maProperties=new Properties(); maProperties.setProperty("/xx/hessianremote.hessianservice", "hessianExporterService"); mapping.setMappings(maProperties); return mapping; } /** * BeanNameUrlHandlerMapping 會自動探測 '/' 開頭的bean當作是一個handler, * 但默認是隻探測當前context裏的bean,不會探測ancestor contexts(父容器), * 若是要探測父容器,那麼設置detectHandlersInAncestorContexts爲true * @return */ @Bean public HandlerMapping beanNameUrlHandlerMapping() { return new BeanNameUrlHandlerMapping(); } /** * 註冊經過掃描註解controller的處理器映射器 * 默認狀況下springmvc會自動註冊BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping這兩個處理器, * 可是當上面手動配置了SimpleUrlHandlerMapping處理器映射器之後,就默認只有這一個處理器,所以,當你還須要 * springmvc自動解析對controller類上方法的http映射,就須要手動配置該映射器處理器。 * SpringMVC默認註冊處理器映射器,可參考源碼:DispatcherServlet 的 initHandlerMappings方法 * @return */ @Bean public HandlerMapping defaultAnnotationHandlerMapping() { return new DefaultAnnotationHandlerMapping(); }
注意:一旦在SpringMVC 中,如同上面手動配置了HandlerMapping,最好把DefaultAnnotationHandlerMappin,BeanNameUrlHandlerMapping這兩個都配置上,不然SpringMvc將不能解析http請求到Controller上。由於SpringMVC默認是會在HandlerMapping爲空狀況下自動註冊這兩個HandlerMapping,可是當你手動註冊過任意HandlerMapping後,就不會再註冊這兩個HandlerMapping。spa
以上能夠參考DispatcherServlet 的 initHandlerMappings方法:debug
1 private void initHandlerMappings(ApplicationContext context) { 2 this.handlerMappings = null; 3 4 if (this.detectAllHandlerMappings) { 5 // Find all HandlerMappings in the ApplicationContext, including ancestor contexts. 6 Map<String, HandlerMapping> matchingBeans = 7 BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); 8 if (!matchingBeans.isEmpty()) { 9 this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values()); 10 // We keep HandlerMappings in sorted order. 11 AnnotationAwareOrderComparator.sort(this.handlerMappings); 12 } 13 } 14 else { 15 try { 16 HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class); 17 this.handlerMappings = Collections.singletonList(hm); 18 } 19 catch (NoSuchBeanDefinitionException ex) { 20 // Ignore, we'll add a default HandlerMapping later. 21 } 22 } 23 24 // Ensure we have at least one HandlerMapping, by registering 25 // a default HandlerMapping if no other mappings are found. 26 if (this.handlerMappings == null) { 27 this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class); 28 if (logger.isDebugEnabled()) { 29 logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default"); 30 } 31 } 32 }
能夠看到26行,就是當沒有手動配置HandlerMapping時,會自動添加默認的HandlerMapping。code