在使用SpringMVC的時候,我們知道需要HandlerMapping定義請求路徑與處理器之間的映射,需要HandlerAdapter來調用處理器方法并傳回一個ModelAndView對象,需要ViewResolver來解析視圖。這些是SpringMVC中最基本的接口。通常我們都需要在SpringMVC的配置檔案中定義好需要使用的HandlerMapping、HandlerAdapter和ViewResolver,基于注解的SpringMVC配置也是類似的。是以一般我們的SpringMVC配置檔案會是如下這樣:
mvc命名空間是Spring提供的一個簡化SpringMVC配置的命名空間,<code><mvc:annotation-driven/></code>會自動在Spring的bean容器中注冊HandlerMapping接口實作RequestMappingHandlerMapping類型的bean和HandlerAdapter接口實作類RequestMappingHandlerAdapter類型的bean。<code><mvc:view-resolvers/></code>是用來快速定義ViewResolver實作的,其中<code><mvc:jsp/></code>會自動定義一個InternalResourceViewResolver類型的ViewResolver。
針對這些比較基本接口,即使我們不定義它們的實作,SpringMVC内部也給了預設的定義,它管這些叫政策。SpringMVC把這些預設政策都定義在一個叫<code>DispatcherServlet.properties</code>的檔案中,它與DispatcherServlet在同一個包中。以下是筆者在使用的4.1.0版本中的DispatcherServlet.properties檔案中的定義。
從上面的定義中我們可以看出來,在使用SpringMVC時,即使你不定義HandlerMapping,SpringMVC預設也會給你定義一個BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping。HandlerAdapter和ViewResolver也是一樣的。還有一些其它的預設政策也請參考DispatcherServlet.properties中。如果預設政策不能滿足你的要求,那麼我們可以在bean容器中定義我們自己對應的實作,這個時候就會應用我們自己的實作了。我們拿初始化HandlerMapping為例,來看一下DispatcherServlet的源碼。
從源碼中我們可以看到,SpringMVC先會從綁定的ApplicationContext中擷取對應的HandlerMapping定義,如果沒有取到就會調用<code>getDefaultStrategies(context, HandlerMapping.class)</code>從預設政策中擷取。它的代碼如下所示。
其中的defaultStrategies就是對應的<code>DispatcherServlet.properties</code>檔案中的内容。
(注:本文是基于SpringMVC4.1.0所寫)