【SpringBoot】springboot中springmvc自動配置分析

springmvc中springmvc自動配置分析


如果對SpringBoot不甚瞭解, 可能會對其just run的做事方式有所顧慮,
可能會對AutoConfiguration的魔法感到有一絲絲未知的恐懼?也許會認爲這個框架太過於簡單無法滿足需要? 不過,
一旦你瞭解SpringBoot,這些疑問句都會變成感嘆句…, SpringBoot對初學者展示了足夠的友好,也同時有極大的靈活性,讓我們自己通過自己的做事風格,打造屬於自己springboot,追隨風的腳步,一起去領略SpringBoot的風采…

本篇討論springboot中springmvc自動配置分析…


本篇博客基於springboot2.1.6:
springmvc自動配置官方文檔

springboot自動配置好了springmvc的大部分配置:

下面是springboot對springmvc的默認配置:

這次的重點分析在WebMvcAutoConfiguration上 .

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

    • 自動配置了ViewResolver:

      viewResolver: 根據方法的返回值,得到視圖對象view,視圖對象決定如何渲染:(轉發?還是重定向?)

      查看WebMvcAutoConfiguration類中WebMvcAutoConfigurationAdapter類的ContentNegotiatingViewResolver方法 :

      在這裏插入圖片描述

    易知,查看ContentNegotiatingViewResolver類中的resolveViewName方法 …

在這裏插入圖片描述

  1. . 易知,此方法的目的是 把所有的視圖對象挨個進行遍歷 …

在這裏插入圖片描述

發現ContentNegotiatingViewResolver就是組合所有的視圖解析器的 …

問題來了?我們如何向boot中添加自己的視圖解析器 …

由上圖可知 , 是遍歷ContentNegotiatingViewResolver類中的viewResolvers . 我們把目光聚焦在viewResolvers

通過分析,發現 在ContentNegotiatingViewResolver中有一個初始化方法:


	@Override
	protected void initServletContext(ServletContext servletContext) {
		Collection<ViewResolver> matchingBeans =
				BeanFactoryUtils.beansOfTypeIncludingAncestors(obtainApplicationContext(), ViewResolver.class).values();
		if (this.viewResolvers == null) {
			this.viewResolvers = new ArrayList<>(matchingBeans.size());
			for (ViewResolver viewResolver : matchingBeans) {
				if (this != viewResolver) {
					this.viewResolvers.add(viewResolver);
				}
			}
		}

由第五行代碼可以發現是從容器中獲取到視圖解析器的 … …

所有 ,我們要定製自己的resolver,只需要將自己的視圖解析器加入到容器中即可 .

測試:

1), 自定義視圖解析器:

在配置類中自定義ViewResolver:

    @Bean
    public myViewResolver addmyViewResolver(){
        return new myViewResolver();
    }
    public static class myViewResolver implements ViewResolver {
        @Override
        public View resolveViewName(String s, Locale locale) throws Exception {
            return null;
        }
    }

2),debug方式測試 :在DispatherServel中 doDispather中加上一個斷點 …

在這裏插入圖片描述

發現有我們自己定義的myviewResolver

  • Automatic registration of Converter, GenericConverter, and Formatter beans.

    • Converter:裝換器 ; 類型使用的Converter , 即是將前端的string類型等數據轉換成各種其他的數據格式 .

    • Formatter , 格式轉換器 日期 .

      也只只需要自己將自定義的格式轉換器放置在容器中就會被自動獲取,如下圖:也是從容器中獲取.

      WebMvcAutoConfiguration類中WebMvcAutoConfigurationAdapte類的方法:

    在這裏插入圖片描述

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

    • springmvc用來轉換http請求和響應的: 如 將一個對象轉換成 json格式 /

    • HttpMessageConverters\ 從容器中獲取;獲取所有的HttpMessageConverter\

      WebMvcAutoConfiguration中的WebMvcAutoConfigurationAdapter類中有一個方法:
      public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties,
      				WebMvcProperties mvcProperties, ListableBeanFactory beanFactory,
      				@Lazy HttpMessageConverters messageConverters,
      				ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
      			this.resourceProperties = resourceProperties;
      			this.mvcProperties = mvcProperties;
      			this.beanFactory = beanFactory;
      			this.messageConverters = messageConverters;
      			this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider
      					.getIfAvailable();
      		}
      

    採用了懶加載的模式初始化HttpMessageConverters.打開HttpMessageConverters方法.

    如果只有一個有參構造器的情況下,一般參數中的值都是要從容器中取出.

    HttpMessageConverters中源碼分析:可看到一些可變參數數組.,是獲取容器中所有的HttpMessageConverter方法

    結論:自己給容器中添加HttpMessageConverters,只需要將自己的組件註冊到容器中(@Bean,@Component)

    還可參閱官方文檔示例:如何自定義converters

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

    定義錯誤代碼生成規則,具體可自行參閱源碼

  • Static index.html support. //靜態資源首頁的訪問, 自行參照源碼

  • Custom Favicon support (covered later in this document).

  • Support for serving static resources, including support for WebJars (covered later in this document)).

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

在這裏插入圖片描述

自定義的ConfigurableWebBindingInitializer來替換默認的,只需將自定義放置到容器中即可

讓我們來參照super.getConfigurableWebBindingInitializer();如何進行自定義配置的?
作用是: 初始化webdataBinder,用來將請求數據和javabean進行一一對應,springmvc數據綁定參閱詳解. 

還有其他的類在org.springframework.boot.autoconfigure.web:web的所有自動場景:

總結:

如何修改springboot的默認配置:

  1. . 由於在springboot底層大量使用了從容器中獲取的設計風格.SpringBoot在自動配置很多組件的時候,先看容器中有沒有用戶自己配置的(@Bean、@Component)如果有就用用戶配置的,如果沒有,才自動配置;如果有些組件可以有多個(比如:ViewResolver)將用戶配置的和自己默認的組合起來,並不會"覆蓋".
    2).要找到springboot中在何處獲的容器中的bean, 和獲取什麼bean …
    參考:
    https://jingyan.baidu.com/article/4ae03de3cbf7383eff9e6bd3.html
    https://www.cnblogs.com/zqLoveSym/p/10565087.html
    https://my.oschina.net/u/3574106/blog/1820871
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章