溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么在SpringBoot中配置靜態(tài)資源

發(fā)布時間:2021-01-14 14:28:00 來源:億速云 閱讀:176 作者:Leah 欄目:開發(fā)技術(shù)

本篇文章給大家分享的是有關(guān)怎么在SpringBoot中配置靜態(tài)資源,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

SpringBoot啟動會默認(rèn)加載很多xxxAutoConfiguration類(自動配置類)

其中SpringMVC的大都數(shù)功能都集中在WebMvcAutoConfiguration類中,根據(jù)條件ConditionalOnxxx注冊類對象;WebMvcAutoConfiguration滿足以下ConditionalOnxxx條件,類是生效的,并把其對象注冊到容器中。

怎么在SpringBoot中配置靜態(tài)資源

那WebMvcAutoConfiguration生效給容器中配置了什么呢?

WebMvcAutoConfigurationAdapter靜態(tài)內(nèi)部類

一.配置文件前綴

我們來看WebMvcAutoConfiguration類中的WebMvcAutoConfigurationAdapter靜態(tài)內(nèi)部類:

怎么在SpringBoot中配置靜態(tài)資源

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

怎么在SpringBoot中配置靜態(tài)資源

怎么在SpringBoot中配置靜態(tài)資源

怎么在SpringBoot中配置靜態(tài)資源

可以看到WebMvcProperties它是與配置文件前綴spring.mvc相關(guān)聯(lián)的。
ResourceProperties它是與配置文件前綴spring.resources相關(guān)聯(lián)。
WebProperties它是與配置文件前綴spring.web相關(guān)聯(lián)。

二.只有一個有參構(gòu)造器

WebMvcAutoConfigurationAdapter靜態(tài)內(nèi)部配置類只有一個有參數(shù)的構(gòu)造器,那它會帶來什么特性呢?
它的有參構(gòu)造器中所有參數(shù)的值都會從容器中確定

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

我們來看下它的參數(shù):

  • 第一個參數(shù)是ResourceProperties resourceProperties 就是我們上面提到的@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})中注冊開啟的第二個類,獲取和spring.resources綁定的所有的值的對象

  • 第二個參數(shù)是WebProperties webProperties 就是我們上面提到的@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})中注冊開啟的第三個類,獲取和spring.web綁定的所有的值的對象

  • 第三個參數(shù)是WebMvcProperties mvcProperties 就是我們上面提到的@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})中注冊開啟的第一個類,獲取和spring.mvc綁定的所有的值的對象

  • 第四個參數(shù)是ListableBeanFactory beanFactory ,這個是Spring的beanFactory,也就是我們的容器。

  • 第五個參數(shù)是ObjectProvider messageConvertersProvider,找到所有的HttpMessageConverters

  • 第六個參數(shù)是ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,找到資源處理器的自定義器

  • 第七個參數(shù)是ObjectProvider dispatcherServletPath,相當(dāng)與找dispatcherServlet能處理的路徑

  • 第八個參數(shù)是ObjectProvider<ServletRegistrationBean<?>> servletRegistrations ,給應(yīng)用注冊原生的Servlet、Filter等等

構(gòu)造器初始化后,我們已經(jīng)把所有的東西從容器中拿到了

三.源碼分析addResourceHandlers方法

所有的資源處理默認(rèn)規(guī)則都在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()));
        }

      }
    }

1.禁用掉靜態(tài)資源的路徑映射

我們打上斷點看它的默認(rèn)規(guī)則是怎么起作用的,首先調(diào)用resourcePropertoes的isAddMappings()方法:

怎么在SpringBoot中配置靜態(tài)資源

判斷this.resourcePropertoes的isAddMappings()方法是不是不為true,

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

  • isAddMappings()方法返回的是this.addMappings的值,如下:

怎么在SpringBoot中配置靜態(tài)資源

也就是說我們可以通過設(shè)置addMappings的值是false還是true來讓這個if語句是否執(zhí)行
我們可以在配置文件中進(jìn)行設(shè)置:

怎么在SpringBoot中配置靜態(tài)資源

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

怎么在SpringBoot中配置靜態(tài)資源

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

addMappings的值如果是true,那么他就不會進(jìn)入if語句中,而是進(jìn)入到else語句中,那么else語句的內(nèi)容都得到了執(zhí)行,下面我們看它是怎么配置靜態(tài)資規(guī)則的。

2.源碼分析webjars的底層規(guī)則

進(jìn)入到else語句中,第一行是Duration cachePeriod = this.resourceProperties.getCache().getPeriod();,它從resourceProperties里面獲取到關(guān)于緩存的相關(guān)值。我們在yaml配置文件中配置一下這個值:

怎么在SpringBoot中配置靜態(tài)資源

緩存時間是以秒為單位的,如下:

怎么在SpringBoot中配置靜態(tài)資源

意思就是我們所有的靜態(tài)資源默認(rèn)可以緩存存儲多少秒

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

怎么在SpringBoot中配置靜態(tài)資源

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

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/路徑,其中還設(shè)置了其靜態(tài)資源的緩存時間為6666秒。

拿jquery來舉例,為什么我們導(dǎo)入jquery之后,我們只需要訪問/webjars/jquery/3.5.1/jquery.js就能夠訪問到/META-INF/resources/webjars/jquery/3.5.1/jquery.js,如下:

怎么在SpringBoot中配置靜態(tài)資源

怎么在SpringBoot中配置靜態(tài)資源

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

怎么在SpringBoot中配置靜態(tài)資源

3.源碼分析默認(rèn)靜態(tài)資源路徑的底層規(guī)則

我們在else里面接著往下debug,接著我們用mvcProperties屬性調(diào)用其getStaticPathPattern()方法

怎么在SpringBoot中配置靜態(tài)資源

  • this.mvcProperties我們剛才在2中講構(gòu)造器時講到的WebMvcProperties mvcProperties 就是我們上面提到的@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})中注冊開啟的第一個類,獲取和spring.mvc綁定的所有的值的對象

  • getStaticPathPattern()方法,這個方法返回的是staticPathPattern的值,如下:

怎么在SpringBoot中配置靜態(tài)資源

staticPathPattern的這個值可以在我們的配置文件中進(jìn)行配置,它的默認(rèn)值是/**,如下:

怎么在SpringBoot中配置靜態(tài)資源

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

怎么在SpringBoot中配置靜態(tài)資源

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

怎么在SpringBoot中配置靜態(tài)資源

接下來我們具體看代碼:

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方法中,注冊前綴這個規(guī)則,剛剛我們在yaml中設(shè)置了前綴為/resource/**,也就是說我們訪問/resource/**下面的所有請求都找我們的this.resourceProperties.getStaticLocations() 路徑,其中也設(shè)置了其靜態(tài)資源的緩存時間為6666秒。
this.resourceProperties.getStaticLocations()方法返回的值是什么呢?我們點進(jìn)去看一下:

怎么在SpringBoot中配置靜態(tài)資源

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

怎么在SpringBoot中配置靜態(tài)資源

可以看到它是一個字符串?dāng)?shù)組,在無參構(gòu)造器中進(jìn)行了初始化,初始化的值是CLASSPATH_RESOURCE_LOCATIONS常量,常量的值為:

“classpath:/META-INF/resources/”, “classpath:/resources/”, “classpath:/static/”, "classpath:/public/“。這就解釋了靜態(tài)資源路徑為什么默認(rèn)為這四個路徑。

以上就是怎么在SpringBoot中配置靜態(tài)資源,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降摹OM隳芡ㄟ^這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI