一、問題引入
我們在SSM中使用SpringMVC的時候,需要由我們自己寫SpringMVC的配置文件,需要用到什么就要自己配什么,配置起來也特別的麻煩。我們使用SpringBoot的時候沒有進行配置,直接就能進行使用,這是為什么呢?
這是因為SpringBoot為我們自動配置好了SpringMVC
1)、我們首先參照官網來看一下關於SpringMVC的自動配置
https://docs.spring.io/spring-boot/docs/2.2.1.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications
Spring MVC Auto-configuration
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
The auto-configuration adds the following features on top of Spring’s defaults:
-
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
-
- 自動配置了ViewResolver(視圖解析器:根據方法的返回值得到視圖對象(View),視圖對象決定如何渲染(轉發?重定向?))
- ContentNegotiatingViewResolver:組合所有的視圖解析器的;
-
- ==如何定制:我們可以自己給容器中添加一個視圖解析器;自動的將其組合進來
-
Support for serving static resources, including support for WebJars (covered later in this document)).
靜態資源文件夾路徑.webjars
- Automatic registration of Converter, GenericConverter, and Formatter beans.
自動注冊了Converter, GenericConverter, and Formatter等
-
- **Converter:轉換器,**比如也面提交的是一個數字,但是頁面的數字是文本類型的,通過轉換器,就能轉換成Integer類型
- Formatter :格式化器,2020-1-1===Date;
-
Support for HttpMessageConverters (covered later in this document).
-
- HttpMessageConverter:SpringMVC用來轉換Http請求和響應的;
- HttpMessageConverter是從容器中確定;獲取所有的HttpMessageConverter;
自己給容器中添加HttpMessageConverter,只需要將自己的組件注冊容器中(@Bean,@Component)
- Automatic registration of MessageCodesResolver (covered later in this document).
定義錯誤代碼生成規則
- Static index.html support.靜態首頁訪問
- Custom Favicon support (covered later in this document).
- Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).
我們可以配置一個ConfigurableWebBindingInitializer來替換默認的;(添加到容器)
初始化WebDataBinder;
請求數據=====JavaBean;
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.
2、擴展SpringMVC
編寫一個配置類(@Configuration),是WebMvcConfigurerAdapter類型;不能標注@EnableWebMvc;
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc
3.全面接管SpringMVC
為什么@EnableWebMvc自動配置就失效了?
1)@EnableWebMvc的核心
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
2)、
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
3)、
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
WebMvcConfigurerAdapter.class })
//容器中沒有這個組件的時候,這個自動配置類才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
4)、@EnableWebMvc將WebMvcConfigurationSupport組件導入進來;
5)、導入的WebMvcConfigurationSupport只是SpringMVC最基本的功能;
4.原理
關於ContentNegotiatingViewResolver
我們點進這個ContentNegotiatingViewResolver ,在下面有一個resolveViewName方法
那么是怎么樣獲取候選的視圖對象的呢?
我們點進getCandidateViews這個方法
那么這個組合邏輯又是什么呢?
返回到我們這里
看到首先是new了一個ContentNegotiatingViewResolver對象
我們點進去,
我們所需要的ViewResolvers是從哪里拿到的呢?
我們接着往下邊看
我們看到,這里有個初始化方法,里邊利用BeanFactoryUtils工具,從容器中獲取所有的視圖解析器,把這些視圖解析器就作為要組合的所有視圖解析器。
那么如何定制我們自己的視圖解析器呢,通過上面的講解,就是:我們只需要自己給容器中添加一個視圖解析器;然后ContentNegotiatingViewResolver就會將其
組合進來。
我們下面舉個簡單的例子給大家演示一下
為了方便,我們就在在SpringBoot的啟動類中創建一個ViewResolver並將其添加到容器中
那么我們怎么判斷是否其作用了呢,我們知道,視圖解析器都會被DisPatcherServlet所掃描到,所有的請求都會被DisPatcherServlet類中的doDispatch方法所攔截
在doDispatch方法上打一個斷點,debug運行,隨便訪問一個url,就能看到結果如下。
結果我們發現,我們自己加入的ViewResovler確實生效了