SpringMVC的HandlerMapping(處理器映射器)


SpringMvc有四種HandlerMapping:BeanNameUrlHandlerMapping ,SimpleUrlHandlerMapping,ControllerClassNameHandlerMapping ,DefaultAnnotationHandlerMapping。

 

1. BeanNameUrlHandlerMapping  (默認)根據controller的name名稱來映射尋找controller,開啟該映射:默認是開啟的

<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, 開啟該映射:

<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:

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"></bean>

 

 4. DefaultAnnotationHandlerMapping 使用注解來映射尋找controller

<!--開啟springMVC注解  -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />  
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>  

使用java代碼配置的方式:

     /**
     *   將請求(/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。

以上可以參考DispatcherServlet 的 initHandlerMappings方法:

 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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM