日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringBoot静态资源配置原理(源码)

發布時間:2025/3/15 javascript 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot静态资源配置原理(源码) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:
我們都知道,SpringBoot啟動會默認加載很多xxxAutoConfiguration類(自動配置類)
其中SpringMVC的大都數功能都集中在WebMvcAutoConfiguration類中,根據條件ConditionalOnxxx注冊類對象;WebMvcAutoConfiguration滿足以下ConditionalOnxxx條件,類是生效的,并把其對象注冊到容器中。

那WebMvcAutoConfiguration生效給容器中配置了什么呢?
WebMvcAutoConfigurationAdapter靜態內部類

一、配置文件前綴

我們來看WebMvcAutoConfiguration類中的WebMvcAutoConfigurationAdapter靜態內部類:

這是一個配置類,配置文件的屬性和xxx進行了綁定。
再看@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})
我們來看當中的WebMvcProperties、ResourceProperties和WebProperties的字節碼文件
分別點進這三個類的字節碼文件中:

可以看到:
WebMvcProperties它是與配置文件前綴spring.mvc相關聯的。
ResourceProperties它是與配置文件前綴spring.resources相關聯。
WebProperties它是與配置文件前綴spring.web相關聯。

二、只有一個有參構造器

WebMvcAutoConfigurationAdapter靜態內部配置類只有一個有參數的構造器,那它會帶來什么特性呢?
它的有參構造器中所有參數的值都會從容器中確定

public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {this.resourceProperties = (Resources)(resourceProperties.hasBeenCustomized() ? resourceProperties : webProperties.getResources());this.mvcProperties = mvcProperties;this.beanFactory = beanFactory;this.messageConvertersProvider = messageConvertersProvider;this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();this.dispatcherServletPath = dispatcherServletPath;this.servletRegistrations = servletRegistrations;this.mvcProperties.checkConfiguration();}

我們來看下它的參數:

  • 第一個參數是ResourceProperties resourceProperties 就是我們上面提到的@EnableConfigurationProperties({WebMvcProperties.class,ResourceProperties.class,
    WebProperties.class})中注冊開啟的第二個類,獲取和spring.resources綁定的所有的值的對象
  • 第二個參數是WebProperties webProperties 就是我們上面提到的@EnableConfigurationProperties({WebMvcProperties.class,
    ResourceProperties.class,WebProperties.class})中注冊開啟的第三個類,獲取和spring.web綁定的所有的值的對象
  • 第三個參數是WebMvcProperties mvcProperties 就是我們上面提到的@EnableConfigurationProperties({WebMvcProperties.class,ResourceProperties.class,
    WebProperties.class})中注冊開啟的第一個類,獲取和spring.mvc綁定的所有的值的對象
  • 第四個參數是ListableBeanFactory beanFactory ,這個是Spring的beanFactory,也就是我們的容器。
  • 第五個參數是ObjectProvider
    messageConvertersProvider,找到所有的HttpMessageConverters
  • 第六個參數是ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,找到資源處理器的自定義器
  • 第七個參數是ObjectProvider dispatcherServletPath,相當于找dispatcherServlet能處理的路徑
  • 第八個參數是ObjectProvider<ServletRegistrationBean<?>> servletRegistrations
    ,給應用注冊原生的Servlet、Filter等等

構造器初始化后,我們已經把所有的東西從容器中拿到了

三、源碼分析addResourceHandlers方法

所有的資源處理默認規則都在addResourceHandlers方法中,如下:

public void addResourceHandlers(ResourceHandlerRegistry registry) {if (!this.resourceProperties.isAddMappings()) {logger.debug("Default resource handling disabled");} else {Duration cachePeriod = this.resourceProperties.getCache().getPeriod();CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();if (!registry.hasMappingForPattern("/webjars/**")) {this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl).setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));}String staticPathPattern = this.mvcProperties.getStaticPathPattern();if (!registry.hasMappingForPattern(staticPathPattern)) {this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl).setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));}}}
  • 禁用掉靜態資源的路徑映射
    我們打上斷點看它的默認規則是怎么起作用的,首先調用resourcePropertoes的isAddMappings()方法:
  • 判斷this.resourcePropertoes的isAddMappings()方法是不是不為true,

    • this.resourcePropertoes我們剛才在2中講構造器時講到的ResourceProperties
      resourceProperties 就是我們上面提到的@EnableConfigurationProperties({WebMvcProperties.class,
      ResourceProperties.class, WebProperties.class})中注冊開啟的第二個類,獲取和spring.resources綁定的所有的值的對象
    • isAddMappings()方法返回的是this.addMappings的值,如下:

    也就是說我們可以通過設置addMappings的值是false還是true來讓這個if語句是否執行
    我們可以在配置文件中進行設置:

    默認它是true,如果是false,那么他就進入if語句中,執行logger.debug("Default resource handling disabled");后結束該方法,else中的所有配置都不生效

    else中的什么配置/webjars/**去哪找等等一些規則都不生效了。
    也就是說我們通過設置add-mappings: false 來禁用掉了靜態資源的路徑映射。
    禁用后所有的靜態資源都訪問不了了。

    addMappings的值如果是true,那么他就不會進入if語句中,而是進入到else語句中,那么else語句的內容都得到了執行,下面我們看它是怎么配置靜態資規則的。

  • 源碼分析webjars的底層規則
    進入到else語句中,第一行是Duration cachePeriod = this.resourceProperties.getCache().getPeriod();,它從resourceProperties里面獲取到關于緩存的相關值。我們在yaml配置文件中配置一下這個值:
  • 緩存時間是以秒為單位的,如下:

    意思就是我們所有的靜態資源默認可以緩存存儲多少秒

    我們debug接著往下走,看到cachePeriod中取到了剛剛yaml中設置的6666,以后我們的瀏覽器就會把我們的靜態資源緩存6666秒:

    debug接著往下走,我們到了注冊"/webjars/**"這個規則的地方:

    if (!registry.hasMappingForPattern("/webjars/**")) {this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl).setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));}

    也就是說我們訪問/webjars下面的所有請求都找我們的classpath:/META-INF/resources/webjars/路徑,其中還設置了其靜態資源的緩存時間為6666秒。
    拿jquery來舉例,為什么我們導入jquery之后,我們只需要訪問/webjars/jquery/3.5.1/jquery.js就能夠訪問到/META-INF/resources/webjars/jquery/3.5.1/jquery.js,如下:

    其緩存時間也可以在瀏覽器中看到為6666秒:

  • 源碼分析默認靜態資源路徑的底層規則
    我們在else里面接著往下debug,接著我們用mvcProperties屬性調用其getStaticPathPattern()方法
    • this.mvcProperties我們剛才在2中講構造器時講到的WebMvcProperties mvcProperties 就是我們上面提到的@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})中注冊開啟的第一個類,獲取和spring.mvc綁定的所有的值的對象
    • getStaticPathPattern()方法,這個方法返回的是staticPathPattern的值,如下:

    staticPathPattern的這個值可以在我們的配置文件中進行配置,它的默認值是/**,如下:

    我們也可以把前綴配置成/resource/**,如下:

    debug接著往下走,接下來調用的方法與上面的webjars是一樣的方法,只不過參數有所不同:

    接下來我們具體看代碼:

    String staticPathPattern = this.mvcProperties.getStaticPathPattern();if (!registry.hasMappingForPattern(staticPathPattern)) {this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl).setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));}

    把剛剛的前綴staticPathPattern得到后作為實參傳入hasMappingForPattern方法中,注冊前綴這個規則,剛剛我們在yaml中設置了前綴為/resource/**,也就是說我們訪問/resource/**下面的所有請求都找我們的this.resourceProperties.getStaticLocations() 路徑,其中也設置了其靜態資源的緩存時間為6666秒。
    this.resourceProperties.getStaticLocations()方法返回的值是什么呢?我們點進去看一下:

    this.resourceProperties.getStaticLocations()返回的是this.staticLocations,這個staticLocations定義如下:

    可以看到它是一個字符串數組,在無參構造器中進行了初始化,初始化的值是CLASSPATH_RESOURCE_LOCATIONS常量,常量的值為:

    • “classpath:/META-INF/resources/”,
    • “classpath:/resources/”,
    • “classpath:/static/”,
    • "classpath:/public/“

    這就解釋了靜態資源路徑為什么默認為這四個路徑。

    四、歡迎頁的處理規則

    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");} }

    總結

    以上是生活随笔為你收集整理的SpringBoot静态资源配置原理(源码)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 精品欧美一区二区精品少妇 | 久久久老熟女一区二区三区91 | 国产偷v国产偷v亚洲高清 | 久久久久久久中文字幕 | 69xxxx国产| 国产精品久久无码 | 欧美高清不卡 | 黄色小说视频网站 | 97香蕉久久超级碰碰高清版 | 成人一区在线观看 | 一级特级黄色片 | 免费99精品国产自在在线 | 91黄色免费视频 | 亚洲区小说区 | 天天干天天色综合 | 欧美sm极限捆绑bd | 国产精品久久999 | 国毛片| 色噜av| 久久y| 久久久久久国产精品一区 | www欧美精品 | 国产最爽的乱淫视频国语对白 | xxxx999| 成人欧美一区二区 | 一级黄色影院 | 午夜av网 | 一级高清毛片 | 亚洲一区二区三区激情 | 一区二区三区视频在线观看免费 | 99视频在线观看免费 | 国产精品国产精品 | 老外黄色一级片 | 欧美理伦片在线播放 | 在线免费观看一区二区 | xxxx日本免费| 色婷婷视频在线观看 | 91亚洲精品久久久蜜桃 | 丰满少妇一区二区三区视频 | 精品国模 | 国产在线精品一区二区三区 | 可以直接看av的网址 | 欧美成人女星 | 浓精喷进老师黑色丝袜在线观看 | 国产精品久久欧美久久一区 | 国产欧美视频在线播放 | 亚洲熟妇av乱码在线观看 | 日韩激情一区二区 | 欧洲视频在线观看 | av网站在线免费播放 | 亚洲一区欧美激情 | 免费观看日批视频 | 国产精品一区二区三区久久久 | 亚洲欧美国产一区二区 | 毛片毛片毛片毛片 | 国产视频网站在线观看 | 国产一级片免费在线观看 | 欧美三级小说 | 国产99re | 日韩狠狠 | 最好看的电影2019中文字幕 | 国产在线观看精品 | 色天堂视频 | 在线观看免费观看在线 | 亚洲欧美在线视频观看 | 美国伊人网 | 日韩av高清在线观看 | 国产精品永久免费观看 | 一个人在线观看免费视频www | 一区二区三区日 | 草逼视频网站 | 久久久久久久久久久久电影 | 97久久国产精品 | 青青草原伊人 | 中文字幕一区二区三区精品 | juliaann欧美二区三区 | 毛片毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 射进来av影视网 | 国产美女福利视频 | 久久久久99精品成人片试看 | 国产精久久久久久 | 嫩模被强到高潮呻吟不断 | 色视频免费在线观看 | 无人在线观看的免费高清视频 | 国产成人精品av在线观 | 欧美日韩 一区二区三区 | jizzjizz黄大片| 欧美成人dvd在线视频 | 天天干夜夜怕 | 亚洲精品久久久久 | 久久99精品国产.久久久久久 | 99视频| 欧美精品一区二区三区视频 | 欧美1区2区 | 九九九久久久久 | 91精品人妻一区二区 | 黄瓜视频在线免费看 | 嫩草影院一区二区 | 怡红院成永久免费人全部视频 |