Springboot中SpringMVC的web配置都在WebMvcAutoConfiguration这个配置类中。WebMvcAutoConfigurationAdapter类中有一个addResourceHandlers方法用来添加资源。
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//如果我们自定义了资源导入的位置,则默认的配置都将会失效
//自定义spring.resources.static-locations=classpath:/coding/
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
//webjars配置
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
//静态资源配置
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
通过源码可知,所有的/webjars/**,都会去classpath:/META-INF/resources/webjars/下找对应资源
webjars是啥?
webjars就是以jar包的方式引入静态资源。
网站:https://www.webjars.org
如果我们要使用jQuery直接将依赖导入即可
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
目录结构:
此时就可以启动项目直接使用localhost:8080/webjars/jquery/3.5.1/jquery.js访问jquery.js
那么我们传统的静态资源在哪里呢?不慌,接着看上面的源码:
点进staticPathPattern看看静态资源是通过什么请求访问的:
/** 请求就是访问静态资源的,继续看Springboot会去哪里加载静态资源,点进staticLocations看看:
通过源码可知,所有的 /**,会去访问如图的四个路径。
加载静态资源的优先级(从大到小): Defaults to classpath:[/META-INF/resources/, /resources/, /static/, /public/].
那么首页访问是什么地址呢?
继续看WebMvcAutoConfiguration类中EnableWebMvcConfigurationr类中的源码
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
FormattingConversionServicemvcConversionService,
ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService,mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
return welcomePageHandlerMapping;
}
private Optional<Resource> getWelcomePage() {
//参照前面的分析,这里的locations就是静态资源访问的四种路径
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
private Resource getIndexHtml(String location) {
//欢迎页就是一个location下的的 index.html 而已
return this.resourceLoader.getResource(location + "index.html");
}
所以说首页就是静态资源访问路径下的index.html