WebMvcAutoConfiguration自动配置
今天来学习下WebMvcAutoConfiguration的自动配置,Spring mvc在web开发过程中是被使用最多的,开发中的各种各样的请求都跟spring mvc有关,所以有必要研究下spring boot中的这个配置类。
通过访问官方说明文档可以看到以下内容:官网地址
Spring Boot为Spring MVC提供了自动配置
自动配置在Spring的默认值之上添加了以下功能
包含
ContentNegotiatingViewResolver和BeanNameViewResolver- 自动配置了ViewResolver(视图解析器:根据方法的返回值得到对应的视图对象(View),视图对象决定如何渲染(是转发 还是重定向))
ContentNegotiatingViewResolver:组合所有的试图解析器- 如何定制:我们可以自己给容器中添加一个视图解析器,即可自动完成
Support for serving static resources, including support for WebJars 静态资源文件夹路径和webjars.
Static
index.htmlsupport. 静态首页Custom
Faviconsupport (详情). 支持自定义网页图标自动注册
Converter,GenericConverter, andFormatterbeans.Converter 转换器 public String hello(User user):数据传参后 接收类型转换使用Converter
Formattrt:格式化器
1
2
3
4
5
6
//在文件中配置日期格
式化的规则
public Formatter<Date> dateFormatter() {
return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件
}自己添加的格式化转换器 只需放入容器即可
Support for
HttpMessageConverters(详情).- HttpMessageConverters 是从容器中确定;获取所有的HttpMessageConverter; 自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中 (@Bean,@Component)
Automatic registration of
MessageCodesResolver(详情).- HttpMessageConverter:SpringMVC用来转换Http请求和响应的;User—Json;
Automatic use of a
ConfigurableWebBindingInitializerbean (covered later in this document).如果只是想扩展mvc功能,那么只需添加自己的@Configuration class 类型为WebMvcConfigurer,但不是 @EnableWebMvc
1
2
3
4
5
6
7
8
9
10//使用WebMvcConfigurer可以来扩展SpringMVC的功能
public class MyMvcConfig implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
//浏览器发送 /atguigu 请求来到 success
registry.addViewController("/atguigu").setViewName("success");
}
}如果要完全控制 Spring MVC 可以添加自己的@Configuration 同时添加注解@EnableWebMvc
不建议全面控制Spring MVC
此外 还有一些静态资源的配置
静态资源映射
默认支持对webjars的路径映射和其他静态资源路径映射
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
26public 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();
//如果未注册 /webjars/** 则执行
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
/** 静态资源路径
String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
*/
//默认静态资源路径映射
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}默认首页配置
spring boot 默认配置了对首页的支持,只需要在静态或模板引擎文件夹下放index.html或index文件即可1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20@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));
return welcomePageHandlerMapping;
}
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");
}WelcomePageHandlerMapping 构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
ApplicationContext applicationContext, Optional<Resource> welcomePage, String staticPathPattern) {
//获取静态路径下的index.html
if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {
logger.info("Adding welcome page: " + welcomePage.get());
setRootViewName("forward:index.html");
}
//获取模板引擎下的index文件
else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
logger.info("Adding welcome page template: index");
setRootViewName("index");
}
}
