SpringMVC三個HandlerMapping實現類解讀

我沒有在划水發表於2020-10-28

1、前言

DispatchServlet需要通過url來找到對應的controller,而在SpringMVC中為我們完成這個工作的元件就是HandlerMapping。

而我們常見的No mapping found for HTTP request with URI……錯誤也是因為HandlerMapping沒有找到對應handler,今天我們就來了解一下,SpringMVC中HandlerMapping的實現類。

2、HandlerMapping的實現類

在HandlerMapping的實現類中,除去抽象類、已棄用的實現類、子介面以及EmptyHandlerMapping空實現之外,我們可以得出三個實現類:

  1. BeanNameUrlHandlerMapping
  2. SimpleUrlHandlerMapping
  3. RequestMappingHandlerMapping

在這裡插入圖片描述
我們來逐一解讀一下這幾個類的作用。

2.1 BeanNameUrlHandlerMapping

該實現類可以把IOC容器中name以"/" 開頭的Bean註冊為handler

簡單介紹一下這個類的使用方式:在xml檔案中,我們只需要在配置bean的時候,加上name屬性就可以將handler註冊上去:

<bean name="/hello.html" class="com.zhengfa.controller.HelloController"/>

需要注意的是,name屬性必須帶上“/”字首,否則BeanNameUrlHandlerMapping是不會將其註冊進去的,關於這一點我們可以在原始碼中驗證:

protected String[] determineUrlsForHandler(String beanName) {
		List<String> urls = new ArrayList<String>();
		if (beanName.startsWith("/")) {
			urls.add(beanName);
		}
		String[] aliases = getApplicationContext().getAliases(beanName);
		for (String alias : aliases) {
			if (alias.startsWith("/")) {
				urls.add(alias);
			}
		}
		return StringUtils.toStringArray(urls);
	}


2.2 SimpleUrlHandlerMapping

該實現類需要我們在xml檔案中手動配置url與handler的對映,使用方式有點類似struts2:

<bean name="helloController" class="com.zhengfa.controller.HelloController"/>
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="urlMap">
            <props>
                <prop key="/hello.html">
                    helloController
                </prop>
            </props>
        </property>
    </bean>


2.3 RequestMappingHandlerMapping

這是最常用的HandlerMapping實現,通過它,我們可以使用註解的形式來標識url與handler的對映:

@Controller("/mvc")
public class HelloController {
    
    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }
    
}


3、SpringMVC中的預設配置

當我們沒有在xml檔案中配置任何HandlerMapping實現類時,SpringMVC會使用預設的實現類,該配置可以在DispatcherServlet.properties中找到:
在這裡插入圖片描述
在此處SpringMVC為我們引入了兩個預設實現類,一個是我們上面講過的BeanNameUrlHandlerMapping。

而另一個DefaultAnnotationHandlerMapping是已經棄用的實現類,在Spring3.1使用新的HandlerMapping 和 HandlerAdapter來支援@Contoller和@RequestMapping註解處理器

需要注意的是,如果我們在xml中配置了HandlerMapping,那麼預設的HandlerMapping就會失效。

相關文章