1、自动配置
Spring Boot 有关的自动配置都在autoconfigure.jar里。
xxxxAutoConfiguration:帮我们给容器中自动配置组件;
xxxxProperties:配置类来封装配置文件的内容;
通过这些类Spring Boot完成自动配置功能。
与web相关的自动配置我们找到org.springframework.boot.autoconfigure.web包,不同版本的Spring Boot包结构可能不同,我使用的是2.1.2版本。
2、webjars资源映射
有关于静态资源映射的配置则是在org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration这个类中,这个类有个内部类叫WebMvcAutoConfigurationAdapter,这个类有个addResourceHandlers方法:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache()
.getCachecontrol().toHttpCacheControl();
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/ 找资源(包括jar包)。而webjars是以jar包的方式引入静态资源,例如:jquery,echarts,Bootstrap等。我们可以去WebJars官网(https://www.webjars.org/)去找我们需要的资源,然后用Maven引入即可:
引入效果:
我们可以使用:/webjars/jquery/3.3.1-1/jquery.js这种方式访问jquery资源。
2、任意静态资源映射
还是addResourceHandlers方法中:
//静态资源文件夹映射
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(
this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
点击找到staticPathPattern和this.resourceProperties.getStaticLocations()的值如下:
staticPathPattern="/**"
this.resourceProperties.getStaticLocations()={
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
所以这个映射规则是将“/**”访问任何静态资源,都去静态资源的文件夹下找。
3、欢迎页映射
WebMvcAutoConfigurationAdapter类的welcomePageHandlerMapping方法
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(
ApplicationContext applicationContext) {
return new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext),
applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
}
主要是getWelcomePage()方法,获取欢迎页页面,然后被this.mvcProperties.getStaticPathPattern()映射点进去可以知道:
private Optional<Resource> getWelcomePage() {
//获取路径
String[] locations = getResourceLocations(
this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml)
.filter(this::isReadable).findFirst();
}
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}
this.mvcProperties.getStaticPathPattern()="/**"
this.resourceProperties.getStaticLocations()={
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
所以就是让那几个静态资源文件夹下的index.html,被"/**"映射。
4、favicon.ico图标映射
WebMvcAutoConfiguration类中的内部类FaviconConfiguration的SimpleUrlHandlerMapping方法
@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
//调用faviconRequestHandler方法
faviconRequestHandler()));
return mapping;
}
@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
//调用resolveFaviconLocations方法
requestHandler.setLocations(resolveFaviconLocations());
return requestHandler;
}
private List<Resource> resolveFaviconLocations() {
String[] staticLocations = getResourceLocations(
//路径
this.resourceProperties.getStaticLocations());
List<Resource> locations = new ArrayList<>(staticLocations.length + 1);
Arrays.stream(staticLocations).map(this.resourceLoader::getResource)
.forEach(locations::add);
locations.add(new ClassPathResource("/"));
return Collections.unmodifiableList(locations);
}
点进去可以知道
this.resourceProperties.getStaticLocations()={
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
所以还是将这几个静态资源文件下的favicon.ico映射成图标。
我们可以在application.properties文件中配置静态资源文件夹位置,可以配多个,以逗号分隔
spring.resources.static-locations=classpath:/hello,classpath:/test