首先要知道SpringBoot在哪个地方(哪个自动配置类中)设置了静态资源映射规则。
在SpringMVC中可以利用.xml配置文件在其中添加mvc标签进行设置设置静态资源映射,如下:
<mvc:resources mapping="/css/**" location="/WEB-INF/templates/css/"/>
<mvc:resources mapping="/fonts/**" location="/WEB-INF/templates/fonts/"/>
<mvc:resources mapping="/js/**" location="/WEB-INF/templates/js/"/>
<mvc:resources mapping="/img/**" location="/WEB-INF/templates/img/"/>
在SpringBoot中由于实现了自动配置,不再使用配置文件进行设置,而是使用了java配置类进行自动配置。所以它一定在WebMVC的相关配置类中:
在WebMvcAutoConfiguration.class下的addResourceHandlers方法用于处理映射问题
addResourceHandlers()方法
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
//如果采用的是自定义的方法设置映射,就采用自定义的映射关系
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
ServletContext servletContext = this.getServletContext();
this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (servletContext != null) {
registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")});
}
});
}
}
/webjars/请求
若用户输入:http://localhost:8080/webjars/**请求:
/请求
若用户发出http://localhost:8080/**请求:
**点入getStaticPathPattern()方法,获取它包括的请求。**它是WebMvcProperties.配置类的一个get方法:
public String getStaticPathPattern() {
return this.staticPathPattern;
}
private String staticPathPattern;//表明这是WebMvcProperties的一个属性
//在WebMvcProperties类的构造器中设置了它的值为:
this.staticPathPattern = "/**";
//同样也有相应的set方法,我们可以通过.yaml(或者.properties)配置文件修改它的Url请求路径:
public void setStaticPathPattern(String staticPathPattern) {
this.staticPathPattern = staticPathPattern;
}
可以在.properties修改它的值:
spring.mvc.static-path-pattern=/demo.....
registration:代表请求对应资源所在的路径。
点击registration.addResourceLocations(this.resourceProperties.getStaticLocations());中的getStaticLocations()方法
public String[] getStaticLocations() {
return this.staticLocations;
}
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
private String[] staticLocations;
这个staticLocations是WebProperties类的内部类Resources的一个属性,在这个内部类的构造器中:
this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
*表明当我们发出http://localhost:8080/*请求时,会到:
classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
当上述的文件夹中有相同的文件时,会按照上述给的在数组String[] CLASSPATH_RESOURCE_LOCATIONS顺序进行遍历,
new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"}
访问顺序:
1、classpath:/META-INF/resources/
2、classpath:/resources/
3、classpath:/static/
4、classpath:/public/
当三个文件夹下都有index.xml
当resources下没有index.xml
这个要将浏览器缓存清除才能显示否则为第一张图的结果
通过探究SpringBoot静态资源映射进一步理解了SpringBoot自动配置的原理。同时加深了配置文件和配置类之间的联系的理解。当自动配置类xxxAutoConfiguration不能满足我们的需求的时候,可以通过在配置文件中(推荐使用yaml)添加我们的属性,而这个配置文件又和xxxProperties相关联通过注解:
@ConfigurationProperties(
prefix = "spring.mvc"
)
相联系。
自动配置类xxxAutoConfiguration要获取到我们的手动修改的属性(通过在配置文件修改)需要在自己的类中加上
@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})
@EnableConfigurationProperties,使使用 @ConfigurationProperties 注解的类生效。即使我们的修改生效