SpringBoot--SpringMVC自動配置

SpringMVC自動配置

1.SpringBoot官方文檔對SpringMVC的默認配置:

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

    • 自動配置了ViewResolver(視圖解析器:根據方法返回值得到視圖對象,試圖對象決定如何渲染)
    • 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 類型轉換器 :String ===> 封裝進去User

    • Formatter 格式化器 :2017-12-17 ===> Date

      public void addFormatters(FormatterRegistry registry) {
          ApplicationConversionService.addBeans(registry, this.beanFactory);
      }
      
      public static void addBeans(FormatterRegistry registry, ListableBeanFactory beanFactory) {
              Set<Object> beans = new LinkedHashSet();
              beans.addAll(beanFactory.getBeansOfType(GenericConverter.class).values());
              beans.addAll(beanFactory.getBeansOfType(Converter.class).values());
      

      所以springboot同時也將容器中所有的Converter Formatter GenericConverter加入到組件中

      自己添加的格式化轉換器,我們只需要放在容器中即可

  • Support for HttpMessageConverters (covered later in this document).

    • HttpMessageConverters : SpringMVC用來轉換Http請求和相應的;(User對象轉換成Json數據)

    • 只有一個構造器給ObjectProvider賦值 ,所以參數直接從容器中獲取, HttpMessageConverters 是從容器中確定,獲取所有的HttpMessageConverter

      private final ObjectProvider<HttpMessageConverters> messageConvertersProvider;
      public WebMvcAutoConfigurationAdapter(…… ObjectProvider<HttpMessageConverters>        messageConvertersProvider…………) {
      this.messageConvertersProvider = messageConvertersProvider;
      

      自己添加的HttpMessageConverter,只需要直接放入容器(@Bean、@Component)

  • Automatic registration of MessageCodesResolver (covered later in this document).

    • 定義錯誤程式碼的生成規則
  • Static index.html support.

    • 靜態首頁訪問
  • Custom Favicon support (covered later in this document).

    • favicon.ico
  • Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

    • 我們可以配置一個ConfigurableWebBindingInitializer 來替換默認的;(添加到容器)

       初始化WebDataBinder
       請求數據===JavaBean   將數據綁定成為我們要封裝的對象,用到類型轉換器,格式化器等等
      ConfigurableWebBindingInitializer 
              public void initBinder(WebDataBinder binder) {
              binder.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
              if (this.directFieldAccess) {
                  binder.initDirectFieldAccess();
        }
      

org.springframework.boot.autoconfigure.web:web的所有自動場景;

2. 擴展SpringMVC

If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.

    <mvc:view-controller path="/hello" view-name="success"/>
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/hello"/>
            <bean></bean>
        </mvc:interceptor>
    </mvc:interceptors>

編寫一個配置類(Configuration),是WebMvcConfigurer 類型,不能標註@EnableWebMvc

@Configuration
//WebMvcConfigurer介面中有很多方法的對應的是以往Springmvc配置文件中的屬性
//使用其來擴展SpringMVC的功能
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //瀏覽器發送/jiat請求來到 success
        registry.addViewController("/jiat").setViewName("success");
    }

}

原理:

  1. WebMvcAutoConfiguration是SpringMVC的自動配置類
  2. 在做其他自動配置時會導入;@Import(EnableWebMvcConfiguration.class)
  3. 容器中所有的WebMvcConfiguration都會起作用
  4. 我們的配置類也會被調用

3.全面接管SpringMVC(在我們的WebMvcConfigurer配置類上加上一個@EnableWebMvc)

SpringBoot對SpringMVC的自動配置不需要了,所有都是我們自己配置,所有的SpringMVC模組自動配置全部失效,包括靜態資源

@EnableWebMvc能使默認配置生效的原因

  1. 添加了@EnableWebMvc後會為容器導入一個WebMvcConfigurationSupport配置類,添加相應組件到容器中
@Import({DelegatingWebMvcConfiguration.class}) //導入一個DelegatingWebMvcConfiguration
public @interface EnableWebMvc {
//為容器添加一個WebMvcConfigurationSupport
@Configuration(
    proxyBeanMethods = false
)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
  1. 而 WebMvcAutoConfiguration 的註解上有一個「@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})」,當存在如果容器中存在WebMvcConfigurationSupport對象時,WebMvcAutoConfiguration 自動配置失效
@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
//如果容器中存在WebMvcConfigurationSupport對象,則以下所有配置不生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {

接管SpringMVC總結:

  1. @EnableWebMvc將WebMvcConfigurationSupport組件導入容器中
  2. WebMvcConfigurationSupport只是SpringMVC的最基本功能
  3. 用戶可以在實現基本功能的WebMvcConfigurationSupport上訂製自己的webmvc

4. 如何修改SpringBoot的默認配置

模式:

  1. SpingBoot在自動配置很多組件的時候,先看容器中有沒有用戶自己配置的(@Bean、@Component)如果有就用用戶配置的,沒有才自動配置,如果有些組件可以多個(ViewResolver)將用戶配置的和自己默認的組合起來
  2. 在SpringBoot中會有非常多的xxxConfigurer幫助我們進行擴展
  3. 在SpringBoot中會有很多的xxxCustomizer幫助我們進行訂製配置