在实际工作中SpringBoot项目应用,有些项目没有前后端分离,静态资源也放在应用中,会碰到如下图的静态资源配置。有些伙伴会跟我有同样疑问静态资源这样放是什么原因?最近刚好有时间,带着多年的疑问去研究,在翻看了源码后,终于解开了多年的疑惑。因此写了此文与伙伴分享,让大伙少走弯路!

springboot配置(SpringBoot之静态资源配置原理)(1)

一 静态资源配置源码分析

1 当实例化resourceHandlerMapping时,调用addResourceHandlers函数,向ResourceHandlerRegistry实例属性locationValues赋值(为静态资源的默认路径),当有静态请求就往默认路径获取相应资源(循环遍历默认路径再拼接上资源名称,获取得到则返回Recource实例)。

1.1 当实例化resourceHandlerMapping时会执行下面addResourceHandlers函数

springboot配置(SpringBoot之静态资源配置原理)(2)

1.2 向ResourceHandlerRegistry实例属性locationValues赋值(为静态资源的默认路径)

springboot配置(SpringBoot之静态资源配置原理)(3)

1.3 下图为步骤
1.2this.resourceProperties.getStaticLocations()的具体值("
classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" ),源码也说明了在默认路径下的资源才会被解析到

springboot配置(SpringBoot之静态资源配置原理)(4)

二 自主定义资源路径

1 在application.properties文件下配置上,SpringBoot2.5.4使用
spring.resources.static-locations无效,当配置上自定义的路径就会把原来的覆盖掉了,原来的失效。

spring.web.resources.static-locations=classpath:/res/

2 使用自定义路径原有配置失效,在源码中的体现如下。

实例化WebProperties后,在执行初始化函数initializeBean时,内部执行
applyBeanPostProcessorsBeforeInitialization,调用后置处理器
ConfigurationPropertiesBindingPostProcessor实例函数
postProcessBeforeInitialization,使用反射调用WebProperties实例中函数public void setStaticLocations(String[] staticLocations)覆盖原值。源码如下图

springboot配置(SpringBoot之静态资源配置原理)(5)

springboot配置(SpringBoot之静态资源配置原理)(6)