SpringBoot學習大綱
一、基于SpringBoot搭建Web工程:
1.1.編碼實現步驟:
a.創建SpringBoot項目
b.選中依賴:選中我們所需要的模塊
1.2.SSM中的WEB開發配置與SpringBoot中WEB開發自動配置對比:
a.SSM中的WEB開發:
- 1.在
SSM 整合時,需要手動配置 Tomcat 、配置 SpringMVC、配置如何掃描包、配置字符過濾器、配置視圖解析器、文件上傳
等,如下圖所示的配置,非常麻煩。
b.SpringBoot中的web開發:
在SpringBoot 中,存在自動配置機制,提高開發效率
- 1.導入web開發的場景:
- 2.引入場景啟動器后,就引入了autoconfigure功能
- 3.@EnableAutoConfiguration注解使用@Import(AutoConfigurationImportSelector.class)批量導入組件
二、SpringBoot在Web場景下的自動配置:
2.1.Web開發相關的自動配置類:
- 1.如下是在引入web開發的場景啟動器后,會找到這些全類名,然后根據這些全類名批量加載自動配置類組件到容器中
- 2.SpringBoot啟動
默認加載 xxxAutoConfiguration(這些類就是自動配置類)這些類
都在如下這個org包中:
- 3.其中與web開發有關的自動配置類都在web目錄中
2.2.SpringBoot對SpringMVC自動配置
a.SpringBoot對SpringMVC自動的默認配置
b.SpringBoot中對SpringMVC的定制化開發:
- 1.全自動的默認配置:
- 含義解釋:保持 SpringBootMVC的默認配置,并且自定義更多的 mvc 配置,如:interceptors, formatters, view controllers 等
- 實現方式:
使用@Configuration注解添加一個 WebMvcConfigurer 類型的配置類,并不要標注 @EnableWebMvc
- 2.手動自動結合:
- 含義解釋:保持 SpringBootMVC的默認配置,但要自定義核心組件實例,比如:RequestMappingHandlerMapping, RequestMappingHandlerAdapter, 或ExceptionHandlerExceptionResolver,
- 實現方式:
@Configuration 標注一個配置類,實現 WebMvcConfigurer 接口,給容器中放一個 WebMvcRegistrations 組件即可
- 3.全手動方式:
- 含義解釋:全面接管 Spring MVC
- 實現方式:
@Configuration 標注一個配置類,并加上 @EnableWebMvc注解,實現 WebMvcConfigurer 接口
2.3.分析WebMvcAutoConfiguration類的源碼:
a.定位SpringMVC相關的自動配置類源碼:
- 1.SpringBoot中對SpringMVC功能的自動配置類是
WebMvcAutoConfiguration
b.WebMvcAutoConfiguration類源碼分析:
1、WebMvcAutoConfiguration類的源碼:
- 可以看到這個類上
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)、@ConditionalOnClass()、ConditionalOnWebApplication
條件注解
2、分析:WebMvcAutoConfiguration類生效條件
- 1.
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })
意思是在DispatcherServletAutoConfiguration、TaskExecutionAutoConfiguration(異步任務)、ValidationAutoConfiguration(數據校驗)配置好了之后,WebMvcAutoConfiguration再進行配置 - 2.
@ConditionalOnWebApplication(type = Type.SERVLET)
如果是web應用就生效,類型是SERVLET、REACTIVE響應式編程 - 3.
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
:容器中有Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class這些Bean才生效,這里我們引入了web場景,所以可以判斷出自動配置類是WebMvcAutoConfiguration
是生效的 - 4.
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
:容器中沒有WebMvcConfigurationSupport這個Bean才生效 - 5.
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
:定義的是優先級
3、其他說明:
- 1.如果創建
xxxConfig類并實現WebMvcConfiger
,就會使WebMvcAutoConfiguration配置類失效
,因為在該類中有@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
這個注解會觸發 - 2.
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
這個注解會觸發的原因是我們在自定義的xxConfig類
中實現了WebMvcConfiger
,點進WebMvcConfiger
這個接口就可以知道它繼承了WebMvcConfigurationSupport
,所以springboot自動幫我們配置好的webMvcAutoConfiguration就會失效,注意只是我們在xxxConfig類中重寫的default失效
c.分析當webMvcAutoConfiguration生效時會自動配置什么:
c1.配置了SpringMVC兼容Rest風格的請求
- HiddenHttpMethodFilter;頁面表單提交Rest請求(GET、POST、PUT、DELETE)
c2.配置了表單內容的過濾器:
- 1.可以配合HiddenHttpMethodFilter過濾器使用
- 2.表單內容Filter,GET(數據放URL后面)、POST(數據放請求體)請求可以攜帶數據,PUT、DELETE 的請求體數據會被忽略,使用OrderedFormContentFilter可以實現PUT、DELETE類型的請求體不被忽略
c3.配置了靜態內部類:WebMvcAutoConfigurationAdapter
1、配置的靜態內部類WebMvcAutoConfigurationAdapter作用:
- 靜態內部類WebMvcAutoConfigurationAdapter的作用就是給容器中放了WebMvcConfigurer組件;給SpringMVC添加各種定制功能
2、介紹靜態內部類WebMvcAutoConfigurationAdapter類所實現的WebMvcConfigurer接口:
====================== SpringBoot2中WebMvcAutoConfigurationAdapter類的源碼===================
- 1.如下可以看到靜態內部類WebMvcAutoConfigurationAdapter僅實現了WebMvcConfigurer接口
====================== SpringBoot3中WebMvcAutoConfigurationAdapter類的源碼=================== - 1.如下可以看到靜態內部類WebMvcAutoConfigurationAdapter實現了WebMvcConfigurer接口
- 2.ctrl + F12可以看到WebMvcConfigurer接口中的所有方法,這些抽象方法提供了配置SpringMVC底層的所有組件的入口:
- 3.下面我對接口中的抽象方法的功能進行了說明:
3、解析靜態內部類WebMvcAutoConfigurationAdapter上標注的注解:
========== ==SpringBoot2中靜態內部類WebMvcAutoConfigurationAdapter上標注的注解 =================
- 1.注解1 @Configuration:
在WebMvcAutoConfigurationAdapter類上有注解@Configuration
,所以說這個類是屬于一個配置類
- 2.注解2 @EnableConfigurationProperties 根據
@EnableConfigurationProperties({WebMvcProperties.class,ResourceProperties.class})
可見有xxxxproperties,這說明配置文件的屬性配置是和實體類xxx綁定在一起的
- 3.由下圖可知:配置文件中
WebMvcProperties==spring.mvc
和ResourceProperties==spring.resources
進行了綁定
- 2.WebMvcProperties分析:
- 3.ResourceProperties分析:
========== ==SpringBoot3中靜態內部類WebMvcAutoConfigurationAdapter上標注的注解 =================
- 1.@EnableConfigurationProperties注解: 根據
@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
可見有xxxxproperties,這說明配置文件的屬性配置是和實體類xxx綁定在一起的
- 2.根據如下源碼可知:
WebMvcProperties對配置文件中的spring.mvc
進行了綁定
- 3.根據如下源碼可知:
WebProperties對配置文件中的spring.web
進行了綁定
4、
擴展知識
:當某個配置類只有一個有參構造器的時候,有參構造器所有參數的值都會從容器中確定
這里的WebMvcAutoConfigurationAdapter配置類就是只有一個有參構造器!!!
,所以所有參數的值都會從容器中確定
ResourceProperties resourceProperties;
獲取和spring.resources綁定的所有的值的對象WebMvcPropertiesmvcProperties
:獲取和spring.mvc綁定的所有的值的對象ListableBeanFactorybeanFactory
:Spring的beanFactory(容器工廠)HttpMessageConverters
:找到所有的HttpMessageConvertersResourceHandlerRegistrationCustomizer
: 找到資源處理器的自定義器(重點)
ServletRegistrationBean
:給應用注冊Servlet,Filter…
c4.配置了message Converters
c5.配置了視圖解析器:
c6.配置了資源處理器:
- 1.
在這個資源處理器方法中中設置了所有資源處理的默認規則
,下面對其中的代碼進行分析:
1、查看
resourceProperties
中的第1個屬性是:isAddMappings,是和靜態資源訪問相關的
- 1.在資源處理器源碼中可以看到先判斷
this.resourceProperties.isAddMappings()是否為真
:
- 2.this.resourceProperties的值是從哪里來的呢?? 根據源碼可知,是
從這個類中的有參構造中獲取到的
- 3.在構造器這里的resourceProperties的值是,
都是從容器中拿到的
2、分析在
isAddMappings()
方法的含義:
- 1.點擊
isAddMappings()
,查看isAddMappings()
源碼
- 2.在
isAddMappings()
方法中返回了isAddMappings的屬性值
- 3.可以看到
isAddMappings屬性的
默認值是true:
- 4.
ResourcesProperties
這個類是和spring.resources
綁定在一起的,我在配置文件中設置isAddMappings
值為false:
- 5.我在配置文件配置后,所有的靜態資源都被禁用,執行在if判斷中的內容后就return了:
3、查看
resourceProperties
中的第二個屬性是:Cache,是和配置緩存策略相關的
- 1.分析緩存配置:
- 2.配置緩存配置時間,緩存時間以秒為單位:
4、再繼續分析下面的代碼:就是判斷webjars請求相關的了:
- 1.當請求是webjars/**。就去資源目錄META-INF/下去查找資源,且同時設置了資源緩存的時間:
- 2.請求測試設置的緩存時間是否生效:
c7.配置了歡迎頁的處理規則:
- 1.
HandlerMapping
:就是處理器映射。在其中保存了每一個Handler能處理哪些請求
@Beanpublic WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),this.mvcProperties.getStaticPathPattern());welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());return welcomePageHandlerMapping;}WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,ApplicationContext applicationContext, Optional<Resource> welcomePage, String staticPathPattern) {if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {//要用歡迎頁功能,必須是/**logger.info("Adding welcome page: " + welcomePage.get());setRootViewName("forward:index.html");}else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {// 調用Controller /indexlogger.info("Adding welcome page template: index");setRootViewName("index");}}
- 2.如下代碼截圖可以看到要用歡迎頁功能,
請求路徑必須是/**
,一旦加了前綴就失效了