官網閱讀
在進行項目編寫前,我們還需要知道一個東西,就是SpringBoot對我們的SpringMVC還做了哪些配置,包括如何擴充,如何定制。
隻有把這些都搞清楚了,我們在之後使用才會更加得心應手。途徑一:源碼分析,途徑二:官方文檔!
Spring MVC Auto-configuration// Spring Boot為Spring MVC提供了自動配置,它可以很好地與大多數應用程式一起工作。Spring Boot provides auto-configuration for Spring MVC that works well with most applications.// 自動配置在Spring預設設定的基礎上添加了以下功能:The auto-configuration adds the following features on top of Spring’s defaults:// 包含視圖解析器Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.// 支援靜态資源檔案夾的路徑,以及webjarsSupport for serving static resources, including support for WebJars // 自動注冊了Converter:// 轉換器,這就是我們網頁送出資料到背景自動封裝成為對象的東西,比如把"1"字元串自動轉換為int類型// Formatter:【格式化器,比如頁面給我們了一個2019-8-10,它會給我們自動格式化為Date對象】Automatic registration of Converter, GenericConverter, and Formatter beans.// HttpMessageConverters// SpringMVC用來轉換Http請求和響應的的,比如我們要把一個User對象轉換為JSON字元串,可以去看官網文檔解釋;Support for HttpMessageConverters (covered later in this document).// 定義錯誤代碼生成規則的Automatic registration of MessageCodesResolver (covered later in this document).// 首頁定制Static index.html support.// 圖示定制Custom Favicon support (covered later in this document).// 初始化資料綁定器:幫我們把請求資料綁定到JavaBean中!Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).
/*如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(攔截器、格式化程式、視圖控制器和其他功能),則可以添加自己的@configuration類,類型為webmvcconfiguer,但不添加@EnableWebMvc。如果希望提供RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定義執行個體,則可以聲明WebMVCregistrationAdapter執行個體來提供此類元件。*/If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.
// 如果您想完全控制Spring MVC,可以添加自己的@Configuration,并用@EnableWebMvc進行注釋。If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
我們來仔細對照,看一下它怎麼實作的,它告訴我們SpringBoot已經幫我們自動配置好了SpringMVC,然後自動配置了哪些東西呢?
ContentNegotiatingViewResolver 内容協商視圖解析器
自動配置了ViewResolver,就是我們之前學習的SpringMVC的視圖解析器;
即根據方法的傳回值取得視圖對象(View),然後由視圖對象決定如何渲染(轉發,重定向)。
我們去看看這裡的源碼:我們找到 WebMvcAutoConfiguration , 然後搜尋ContentNegotiatingViewResolver。找到如下方法!
@Bean@ConditionalOnBean(ViewResolver.class)@ConditionalOnMissingBean(name = "viewResolver", value = ContentNegotiatingViewResolver.class)public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) { ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); resolver.setContentNegotiationManager(beanFactory.getBean(ContentNegotiationManager.class)); // ContentNegotiatingViewResolver使用所有其他視圖解析器來定位視圖,是以它應該具有較高的優先級 resolver.setOrder(Ordered.HIGHEST_PRECEDENCE); return resolver;}
我們可以點進這類看看!找到對應的解析視圖的代碼;
@Nullable // 注解說明:@Nullable 即參數可為nullpublic View resolveViewName(String viewName, Locale locale) throws Exception {
RequestAttributes attrs = RequestContextHolder.getRequestAttributes(); Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes");
List<MediaType> requestedMediaTypes = this.getMediaTypes(((ServletRequestAttributes)attrs).getRequest()); if (requestedMediaTypes != null) {
// 擷取候選的視圖對象 List<View> candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes); // 選擇一個最适合的視圖對象,然後把這個對象傳回
View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs);
if (bestView != null) { return bestView; }
} // .....}
我們繼續點進去看,他是怎麼獲得候選的視圖的呢?
getCandidateViews中看到他是把所有的視圖解析器拿來,進行while循環,挨個解析!
Iterator var5 = this.viewResolvers.iterator();
是以得出結論:ContentNegotiatingViewResolver 這個視圖解析器就是用來組合所有的視圖解析器的
我們再去研究下他的組合邏輯,看到有個屬性viewResolvers,看看它是在哪裡進行指派的!
protected void initServletContext(ServletContext servletContext) {
// 這裡它是從beanFactory工具中擷取容器中的所有視圖解析器 // ViewRescolver.class 把所有的視圖解析器來組合的
Collection<ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.obtainApplicationContext(), ViewResolver.class).values();
ViewResolver viewResolver; if (this.viewResolvers == null) { this.viewResolvers = new ArrayList(matchingBeans.size());
} // ...............}
既然它是在容器中去找視圖解析器,我們是否可以猜想,我們就可以去實作一個視圖解析器了呢?
我們可以自己給容器中去添加一個視圖解析器;這個類就會幫我們自動的将它組合進來;我們去實作一下

ps:為什麼添加@EnableWebMvc注解後自動配置的mvc失效
檢視@EnableWebMvc注解
發現導入一個類
檢視發現繼承WebMvcConfigurationSupport類
而檢視WebMvc自動配置類發現當存在WebMvcConfigurationSupport類時自動配置失效