ref. 狂神说
Spring Boot 最大的特点就是自动装配,使用起来非常简单:
总之,需要深入理解SpringBoot自动配置原理。
需要考虑的一个问题:在Web项目中会涉及到许多静态资源,比如css、js、html等文件,Spring Boot 如何处理这些静态资源文件?
回顾以前的Web应用,一般main目录下会有一个文件夹webapp,将所有静态页面导入这个目录里的。但是,现在pom中的打包方式是jar,在这种方式下,Spring Boot应该在哪里放置静态资源文件实现页面呢?
在Spring Boot中,SpringMVC的web配置都在WebMvcAutoConfiguration
这个配置类中,在这个类中有一个静态内部类WebMvcAutoConfigurationAdapter
中有很多配置方法,其中有一个方法:addResourceHandlers 添加资源处理,源码如下:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
// 第一种方式:WebJars映射
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
// 第二种方式:默认静态资源映射
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
registration.addResourceLocations(resource);
}
});
}
Spring Boot默认提供了以下3种静态资源映射规则:
通过以上源码可以看出:所有的 /webjars/**
, 都需要去classpath:/META-INF/resources/webjars/
找对应的前端静态资源;
WebJars 是将客户端(浏览器)资源(JavaScript,Css等)打成 Jar 包文件,以对资源进行统一依赖管理。WebJars 的 Jar 包部署在 Maven 中央仓库上;
WebJars官网WebJars - Web Libraries in Jars;
Webjars本质就是以jar包的方式引入项目的静态资源;
一个简单的测试,如要使用jQuery:
pom.xml
:<dependency>
<groupId>org.webjarsgroupId>
<artifactId>jqueryartifactId>
<version>3.6.0version>
dependency>
Spring Boot项目中引入的 jquery 的 jar包结构:
访问:只要是静态资源,SpringBoot就会去对应的路径寻找资源,这里访问http://localhost:8555/webjars/jquery/3.6.0/jquery.js:
Spring Boot默认提供了静态资源处理,使用WebMvcAutoConfiguration中的配置各种属性。还是查看上述源码进行分析:
进入getStaticPathPattern
方法:
public String getStaticPathPattern() {
return this.staticPathPattern;
}
//再继续进入staticPathPattern
/**
* Path pattern used for static resources.
*/
private String staticPathPattern = "/**";
通过上述源码:找到staticPathPattern发现第二种映射规则 :/** 。即访问当前的项目任意资源,它会执行resourceProperties.getStaticLocations()
,进入getStaticLocations
方法查看:
public String[] getStaticLocations() {
return this.staticLocations;
}
// 再继续进入staticLocations
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
// 再继续进入CLASSPATH_RESOURCE_LOCATIONS
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
根据上述源码分析得出,当访问项目中的任意资源(即“/**”)时,Spring Boot 会默认从以下路径中查找资源文件:
// 优先级由高到低
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
如图所示:
一个简单的测试:
在resources/static/
这个目录下放一张照片:
启动项目访问http://localhost:8555/KeyNG.jpg:
其他三种位置类似,也是在resources/
目录下创建对应的文件夹,像上述一样直接访问静态资源即可。
方式一:在配置文件中配置静态资源路径
可以通过在配置文件中配置spring.web.resources.static-locations
属性来指定静态资源文件的路径,配置spring.mvc.static-path-pattern
属性指定静态资源访问模式;
一旦自己定义了静态文件夹的路径,原来的自动配置就都会失效了。
简单测试一下:
方式二:重写addResourceHandlers方法自定义资源映射目录
可以通过自定义一个配置类,实现WebMvcConfigurer接口,然后实现该接口的addResourceHandlers方法;
示例:
新建一个配置类如下:
package com.ano.hello.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class PicsMvcConfig implements WebMvcConfigurer {
/**
* 通过addResourceHandler添加映射路径;
* 再通过addResourceLocations来指定路径
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("pics/**")
.addResourceLocations("classpath:/static/pics/");
}
}
重启项目访问http://localhost:8555/pics/piano.jpg
addResourceHandlers方法中,addResourceLocations
指的是静态文件放置的目录,addResoureHandler
指的是对外暴露的访问路径;
也可以指定外部的目录也很简单,也是直接在addResourceLocations
指定即可。
index.html
被称为静态首页或者欢迎页,会被 /** 映射,也就是说,当访问“/”或者“/index.html”时,都会跳转到该静态首页(欢迎页);