在加入SpringBoot的Web的starter后,自动配置类做了如下工作:
- 内容协商解析器和BeanName视图解析器
- 静态资料(包括webjars)
- 自动注册Convert、GenericConvert、Formatter
- 自动注册HttpMessageConverts
- 自动注册MessageCodesResolver(用于国际化,目前已经很少使用这个方案了)
- 静态index.html支持
- 自定义Favicon
- 自动使用ConfigurableWebBindingInitializer(DataBinder负责将请求数据绑定到JavaBean上)
静态资源访问
只要静态资源防止在/static
、/public
、/resources
、/META-INF/resources
目录下,可以通过当前项目根路径 / 静态资源名
访问
原理是静态映射/**。请求进来后,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源处理器也找不到则相应404页面。
可进行如下配置:
1
2
3
4
5
6
7
8
|
spring:
mvc:
static-path-pattern: /res/**
resources:
static-locations: [classpath:/haha/]
|
配置了前缀后,访问项目根路径 / static-path-pattern / 静态资源名
后,会自动在各个静态目录下查找。配置了static-locations后,则需要将静态文件放置在该目录中。一般来说,我们会配置static-path-pattern,方便进行权限管理(前后端分离项目中,基本用不到这个东西)。
webjars是一个非常有意思的技术,就是将一些js文件通过jar包的方式进行管理,这些js文件会被自动放置在webjars目录下。可用该地址访问:http://localhost:8080/webjars/jquery/3.5.1/jquery.js
1
2
3
4
5
6
7
8
|
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
|
静态资源路径下的index.html将会被作为欢迎页。这个地方有个Bug,可以配置静态资源路径,但是不可以配置静态资源的访问前缀,否则导致index.html不能被默认访问。
1
2
3
4
5
6
7
8
|
spring:
# mvc:
# static-path-pattern: /res/** 这个会导致welcome page功能失效
resources:
static-locations: [classpath:/haha/]
|
将favicon放在静态资源目录下即可被浏览器自动访问到。
静态资源配置原理
如何进行配置的,首先WebMvcAutoConfiguration配置生效:
1
2
3
4
5
6
7
8
9
10
11
12
|
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
}
|
这个类并没有配置太核心的东西,但是这个类里面的静态内部类WebMvcAutoConfigurationAdapter
集成了WebMVCConfigurer,才是配置的核心:
1
2
3
4
5
6
7
8
9
|
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
}
|
WebMvcAutoConfigurationAdapter
构造函数接受的参数如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
/*
resourceProperties:获取和spring.resources绑定的所有的值的对象
mvcProperties:获取和spring.mvc绑定的所有的值的对象
beanFactory:Spring的beanFactory
messageConvertersProvider:找到所有的HttpMessageConverters
resourceHandlerRegistrationCustomizerProvider:找到资源处理器的自定义器
dispatcherServletPath:
servletRegistrations:给应用注册Servlet、Filter等
*/
public WebMvcAutoConfigurationAdapter(
ResourceProperties resourceProperties,
WebMvcProperties mvcProperties,
ListableBeanFactory beanFactory,
ObjectProvider<HttpMessageConverters> messageConvertersProvider,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
ObjectProvider<DispatcherServletPath> dispatcherServletPath,
ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
this.resourceProperties = resourceProperties;
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConvertersProvider = messageConvertersProvider;
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
this.dispatcherServletPath = dispatcherServletPath;
this.servletRegistrations = servletRegistrations;
}
|
WebMvcAutoConfigurationAdapter
配置资源处理的默认规则:
- 针对webjars进行了配置
- 针对静态资源进行了配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@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));
}
}
|
WebMvcAutoConfigurationAdapter
配置欢迎页处理规则:
1
2
3
4
5
6
7
8
9
10
11
12
|
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
return welcomePageHandlerMapping;
}
|