SpringBoot的Web自动配置和默认功能、WebMvcAutoConfiguration原理
目录
- 1. 自动配置
- 2. 提供的默认功能
- 3. WebMvcAutoConfiguration原理
- 3.1 生效条件
- 3.2 效果
- 3.3 WebMvcConfigurer接口
- 3.4 为什么容器中放一个WebMvcConfigurer就能配置底层行为
SpringBoot的Web开发能力,由SpringMVC提供
1. 自动配置
查看org.springframework.boot:spring-boot-autoconfigure:3.1.1\META-INF\spring\org.springframework.boot.autoconfigure.AutoConfiguration.imports,可以看到web相关的自动配置类如下:
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
这些类通过配置类xxxProperties.class,绑定了配置文件的一些配置项
- SpringMVC的所有配置
spring.mvc
- Web场景通用配置
spring.web
- 文件上传配置
spring.servlet.multipart
- 服务器的配置
server
。比如编码方式
2. 提供的默认功能
- 包含了ContentNegotiatingViewResolver和BeanNameViewResolver组件,方便视图解析
- 默认的静态资源处理机制: 静态资源放在static文件夹下即可直接访问
- 自动注册了Converter、GenericConverter、Formatter组件,适配常见数据类型转换和格式化需求。如配置文件自定义的日期属性,转换再格式化为java Bean的日期属性
- 支持HttpMessageConverters,可以方便返回json等数据类型,将java Bean直接返回成json数据
- 注册MessageCodesResolver,方便国际化及错误消息处理
- 支持静态index.html
- 自动使用ConfigurableWebBindingInitializer,实现消息处理、数据绑定、类型转化、数据校验等功能。即前端传过来的参数,转换成java Bean
注意:
- 如果想保持springboot mvc的默认配置,并且自定义更多的mvc配置,如:interceptors、formatters、view controllers等。可以添加@Configuration注解到一个类上,再让这个类继承WebMvcConfigurer接口,并不要标注@EnableWebMvc
- 如果想保持springboot mvc的默认配置,但要自定义核心组件实例,比如:RequestMappingHandlerMapping、RequestMappingHandlerAdapter、ExceptionHandlerExceptionResolver,给容器中放一个WebMvcRegistrations组件即可
- 如果想全面接管Spring MVC,可以添加@Configuration注解到一个类上,再让这个类继承WebMvcConfigurer接口,并不要标注@EnableWebMvc
方式 | 用法 | 效果 |
---|---|---|
全自动 | 直接编写控制器逻辑 | 全部使用自动配置默认效果 |
手自一体 | @Configuration + 配置WebMvcConfigurer + 配置WebMvcRegistrations。不要标注@EnableWebMvc | 保留自动配置效果,手动设置部分功能,定义MVC底层组件 |
全手动 | @Configuration + 配置WebMvcConfigurer。标注@EnableWebMvc | 禁用自动配置效果,全手动设置 |
3. WebMvcAutoConfiguration原理
3.1 生效条件
@AutoConfiguration(
after = {DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class}
) // 在这些自动配置之后。其中TaskExecutionAutoConfiguration是做异步任务的,ValidationAutoConfiguration是做数据校验的
@ConditionalOnWebApplication(
type = Type.SERVLET
) // 如果是web应用,且类型是SERVLET就生效,REACTIVE响应式web不生效
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class}) // 容器中没有这个Bean,才生效。默认就是没有
@AutoConfigureOrder(-2147483638) // 自动配置优先级
@ImportRuntimeHints({WebResourcesRuntimeHints.class}) // 导入运行时的指标统计
3.2 效果
- 放了两个Filter:
- HiddenHttpMethodFilter;页面表单提交Rest请求。表单默认只能提交GET、POST请求,有了这个Filter就能提交PUT、DELETE请求了
b. FormContentFilter: 表单内容Filter,配合HiddenHttpMethodFilter使用。默认GET(数据放URL后面)、POST(数据放请求体)请求可以携带数据,PUT、DELETE的请求体数据会被忽略,加了这个Filter后PUT和DELETE就能携带数据了
- HiddenHttpMethodFilter;页面表单提交Rest请求。表单默认只能提交GET、POST请求,有了这个Filter就能提交PUT、DELETE请求了
- 给容器中放了WebMvcConfigurer组件。具体如下:
@Configuration(
proxyBeanMethods = false
)
@Import({EnableWebMvcConfiguration.class}) // 额外导入了其他配置
@EnableConfigurationProperties({WebMvcProperties.class, WebProperties.class})
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
......省略部分......
}
所有的功能最终会和配置文件进行绑定。WebMvcProperties绑定了spring.mvc
开头的配置,WebProperties绑定了spring.web
开头的配置
3.3 WebMvcConfigurer接口
其中WebMvcConfigurer给SpringMVC添加各种定制功能,配置了SpringMVC底层的所有组件入口。如下所示:
// 路径匹配。如对RestMapping("/hello/**")进行匹配
default void configurePathMatch(PathMatchConfigurer configurer)
// 内容协商
default void configureContentNegotiation(ContentNegotiationConfigurer configurer)
// 异步支持
default void configureAsyncSupport(AsyncSupportConfigurer configurer)
// 默认处理:默认接收: /。静态资源和动态资源都由SpringMVC来处理
default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
// 格式化器。如日期格式化
default void addFormatters(FormatterRegistry registry)
// 请求拦截器
default void addInterceptors(InterceptorRegistry registry)
// 添加资源处理器:处理静态资源规则。比如指定图片、css、js的路径(根路径、classpath、其它)
default void addResourceHandlers(ResourceHandlerRegistry registry)
// 前后端跨域规则
default void addCorsMappings(CorsRegistry registry)
// 视图控制器:/a直接跳转到xxx.html页面
default void addViewControllers(ViewControllerRegistry registry)
// 视图解析
default void configureViewResolvers(ViewResolverRegistry registry)
// Controller请求接收参数解析器
default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers)
// Controller请求返回值处理器
default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers)
// 消息转化器
default void configureMessageConverters(List<HttpMessageConverter<?>> converters)
// 扩展:消息转换
default void extendMessageConverters(List<HttpMessageConverter<?>> converters)
// 配置系统异常解析器
default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers)
// 扩展:异常解析器
default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers)
default Validator getValidator()
default MessageCodesResolver getMessageCodesResolver()
3.4 为什么容器中放一个WebMvcConfigurer就能配置底层行为
- WebMvcAutoConfiguration是一个自动配置类,它里面有一个EnableWebMvcConfiguration
- EnableWebMvcConfiguration继承于DelegatingWebMvcConfiguration,这两个都生效
- DelegatingWebMvcConfiguration利用DI把容器中所有WebMvcConfigurer注入进来
- 别人调用
DelegatingWebMvcConfiguration
的方法配置底层规则,而它调用所有WebMvcConfigurer的配置底层方法