静态资源
Spring Boot 内置静态资源处理,无需额外配置即可托管 CSS、JS、图片等文件。
默认资源目录
Spring Boot 按如下优先级顺序查找静态资源:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/ ← 最常用
classpath:/public/
即将文件放在 src/main/resources/static/ 下,访问 /style.css 即可自动映射到该文件。
src/main/resources/
└── static/
├── css/
│ └── main.css → GET /css/main.css
├── js/
│ └── app.js → GET /js/app.js
└── images/
└── logo.png → GET /images/logo.png
自定义资源路径
# application.yml
spring:
web:
resources:
static-locations:
- classpath:/static/
- classpath:/my-assets/ # 追加自定义目录
- file:/opt/app/uploads/ # 文件系统路径(生产环境上传文件)或通过 Java 配置更细粒度地控制:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 将 /uploads/** 映射到文件系统目录
registry.addResourceHandler("/uploads/**")
.addResourceLocations("file:/opt/app/uploads/");
// 将 /docs/** 映射到 classpath 内的目录
registry.addResourceHandler("/docs/**")
.addResourceLocations("classpath:/static/docs/");
}
}缓存控制
默认行为
Spring Boot 默认为静态资源设置 1 年缓存(Cache-Control: max-age=31536000)。
自定义缓存策略
spring:
web:
resources:
cache:
period: 3600 # 缓存时长(秒),0 = 禁用缓存
cachecontrol:
max-age: 7d # 浏览器缓存 7 天
cache-public: true # 允许 CDN 缓存
no-cache: false@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(Duration.ofDays(30))
.cachePublic());
// 开发环境:禁用缓存,方便调试
registry.addResourceHandler("/dev/**")
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.noStore());
}内容版本化(Cache Busting)
文件内容发生变化时,URL 自动变化,使 CDN/浏览器缓存失效:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(Duration.ofDays(365)))
.resourceChain(true)
.addResolver(new VersionResourceResolver()
.addContentVersionStrategy("/**")); // 按内容 MD5 生成版本号
}
// 注册 ResourceUrlEncodingFilter,使 Thymeleaf 中的 @{} 自动加版本号
@Bean
public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
return new ResourceUrlEncodingFilter();
}
}Thymeleaf 模板中引用资源时会自动转换:
<!-- 源代码 -->
<link th:href="@{/static/css/main.css}" rel="stylesheet">
<!-- 渲染输出(URL 包含内容 hash) -->
<link href="/static/css/main-a3f7c9b2.css" rel="stylesheet">Thymeleaf 模板详见 Thymeleaf。
WebJars
通过 Maven/Gradle 引入前端库,无需手动管理 JS/CSS 文件:
// build.gradle
dependencies {
implementation 'org.webjars:bootstrap:5.3.0'
implementation 'org.webjars:jquery:3.7.0'
implementation 'org.webjars.npm:vue:3.3.4'
// webjars-locator 省去版本号前缀,推荐
implementation 'org.webjars:webjars-locator-core:0.55'
}webjars-locator-core 存在时,可以省略 URL 中的版本号:
<!-- 不使用 webjars-locator(需带版本号) -->
<script src="/webjars/jquery/3.7.0/jquery.min.js"></script>
<!-- 使用 webjars-locator(自动解析版本) -->
<script src="/webjars/jquery/jquery.min.js"></script>欢迎页(Welcome Page)
Spring Boot 自动将静态资源目录下的 index.html 作为根路径欢迎页:
static/index.html → GET /
也可以通过 Controller 自定义欢迎页:
@Controller
public class HomeController {
@GetMapping("/")
public String index() {
return "forward:/index.html"; // 转发到静态文件
}
}favicon.ico
将 favicon.ico 放到以下任意位置即可自动生效:
src/main/resources/static/favicon.ico
src/main/resources/favicon.ico
禁用 favicon(减少不必要请求):
spring:
mvc:
favicon:
enabled: false # Spring Boot 2.x(3.x 默认由浏览器处理)与 Spring Security 配合
Spring Security 默认会拦截所有请求,需要显式放行静态资源:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
// 放行静态资源
.requestMatchers(
PathRequest.toStaticResources().atCommonLocations()
).permitAll()
// 放行自定义路径
.requestMatchers("/uploads/**", "/webjars/**").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
}PathRequest.toStaticResources().atCommonLocations() 自动匹配 /css/**、/js/**、/images/**、/webjars/**、/favicon.ico 等标准路径。
Spring Security 详见 安全。
生产环境:Nginx 托管静态资源
Spring Boot 内置的静态资源处理适合开发和小规模部署,生产环境建议用 Nginx 直接托管:
server {
listen 80;
# 静态资源由 Nginx 直接返回,不经过 Spring Boot
location /static/ {
alias /opt/app/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
location /uploads/ {
alias /opt/app/uploads/;
expires 7d;
}
# 其余请求代理到 Spring Boot
location / {
proxy_pass http://127.0.0.1:8080;
}
}构建时将 src/main/resources/static/ 复制到 /opt/app/static/,与应用部署解耦。
容器化部署详见 Docker部署。