29.1.1 Spring MVC Auto-configuration(以下翻译自官方文档)
Spring Boot为Spring MVC提供了适用于大多数应用的自动配置支持。
以下是对Spring MVC默认支持:
- 自动配置了ContentNegotiatingViewResolver和BeanNameViewResolver两个视图解析器。
- 支持静态资源,包括webjars(官方文档会有说明)
- Converter, GenericConverter和 Formatter bean类的自动化装配。
- 支持HttpMessageConverters(官方文档会有说明)。
- MessageCodesResolver自动注册。
- 支持index.html静态页面。
- 支持自定义Favicon(网站图标)。
- ConfigurableWebBindingInitializer自动使用
如果你想保留Spring Boot MVC原有的功能而且还想添加额外MVC配置(interceptors,formatter,视图控制器view controller或者其他功能),你可以添加你自己@Configuration配置但没有@EnableWebMvc的WebMvcConfigurer类,如果你希望自定义RequestMappingHandlerMapping、RequestMappingHandlerAdapter或者ExceptionHandlerExceptionResolver对象。
你可以声明一个 WebMvcRegistrationsAdapter 对象去提供这些组件。
如果你想完全控制Spring MVC。你能添加自定义@Configuration和@EnableWebMvc注解的类。
上述内容的理解
1.视图解析器的自动配置
ContentNegotiatingViewResolver类的作用是组合所有的视图解析器。
从源码可以看出:
//BeanFactoryUtils.beansOfTypeIncludingAncestors(this.obtainApplicationContext(), ViewResolver.class).values();
//后续代码会将所有视图解析器对象放入一个ArrayList对象属性中。
那么该如何自定义视图解析器呢?
前面代码表示其是会从BeanFactory中获取视图解析器,所以我们完全可以自定义一个Java配置类,将自定义的一个试图解析对象放入spring容器即可。
很简单,就不演示了。
2.静态资源的支持包括index.html静态页面和favicon前面都学过,这里不总结了。
3. formatter和converter
- formatter即格式化对象,比如格式化日期类型。
- converter即转换器类,比如讲众多属性转换为一个对象。
两者的自动配置属于Spring MVC内容,无一例外的被包含在WebMvcConfiguration中,都是根据类型从spring容器中获取。
代码一目了然:
public class WebMvcConfiguration {
public void addFormatters(FormatterRegistry registry) {
Iterator var2 = this.getBeansOfType(Converter.class).iterator();
while(var2.hasNext()) {
Converter<?, ?> converter = (Converter)var2.next();
registry.addConverter(converter);
}
var2 = this.getBeansOfType(GenericConverter.class).iterator();
while(var2.hasNext()) {
GenericConverter converter = (GenericConverter)var2.next();
registry.addConverter(converter);
}
var2 = this.getBeansOfType(Formatter.class).iterator();
while(var2.hasNext()) {
Formatter<?> formatter = (Formatter)var2.next();
registry.addFormatter(formatter);
}
}
}
所以自定义一个formatter
@Configuration
public class DiyFormatterAutoConfiguration {
private class DiyFormatter implements Formatter{}
@Bean
@ConditionalOnMissingBean({DiyFormatter.class})
@ConditionalOnProperty{
Prefix='spring.mvc';
name={'diy-formatter'};
}
@AutoConfigureOrder(-2147483638)
public DiyFormatter diyFormatter(){
return new DiyFormatter();
}
}
converter和GenericConverter同理。
4. 支持HttpMessageConverters
HttpMessageConverter就是一个策略接口, 用来将http请求转为某个对象, 或许将http响应转为指定类型的对象。
public interface HttpMessageConverter<T> {
//检测参数clazz指定的类型是否可以被该转换器读取
boolean canRead(Class<?> clazz, MediaType mediaType);
//检测参数clazz指定的类型是否可以被该转换器写入
boolean canWrite(Class<?> clazz, MediaType mediaType);
//获取该转换器支持的媒体类型列表
List<MediaType> getSupportedMediaTypes();
//从输入信息中读取指定类型对象
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
// 将指定的对象写入到输出
void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
}
其自动配置与上述formatter同理,具体略。
5.后面的MessageCodeResolver定义错误代码生成规则的一个类,略
6. ConfigurableWebBindingInitializer
顾名思义,此类是用来初始化web数据绑定器的。
而web数据绑定器是用来将前台传入的数据绑定到相关的bean中的,里面牵扯到的数据类型转换什么的也会用到前面提到的formatter等。
public class WebMvcConfiguration {
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
try {
return (ConfigurableWebBindingInitializer)this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
} catch (NoSuchBeanDefinitionException var2) {
return super.getConfigurableWebBindingInitializer();
}
}
}
很清楚,如何自定义同上。
7. 扩展Spring MVC
扩展SpringMVC,我以添加view-controller为例:
在SpringMVC项目下添加view-controller:
<view-controller path="/hsw" view-name="success.html"/>
在Spring boot中:
@Configuration
public class MyWebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/hsw").setViewName("success.html");
}
}
新建一个类实现WebMvcConfigurer(视频中所说的是继承WebMvcConfigurer,但这个抽象类也是实现了WebMvcConfigurer接口,我猜这是因为jdk1.8支持了接口默认方法的原因吧!因为我们在实现接口时是选择性地实现方法的,而不是每一个方法都要实现,所以以前版本是会用抽象类实现默认方法实现。)然后实现相应的方法就行了。
原理:1. WebMvcAutoConfiguration是SpringMVC的默认自动配置类。2. 自动配置类中有个静态内部类EnableWebMvcConfiguration,其父类DelegatingWebMvcConfiguratio有个方法·
public void setConfigurers(List<WebMvcConfigurer> configurers) {
能获取我们自定义实现的所有配置类。然后在静态内部类中将配置给添加到容器中。
网友评论