当前位置: 首页 > article >正文

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,绑定了配置文件的一些配置项

  1. SpringMVC的所有配置spring.mvc
  2. Web场景通用配置spring.web
  3. 文件上传配置spring.servlet.multipart
  4. 服务器的配置server。比如编码方式

2. 提供的默认功能

  1. 包含了ContentNegotiatingViewResolver和BeanNameViewResolver组件,方便视图解析
  2. 默认的静态资源处理机制: 静态资源放在static文件夹下即可直接访问
  3. 自动注册了Converter、GenericConverter、Formatter组件,适配常见数据类型转换和格式化需求。如配置文件自定义的日期属性,转换再格式化为java Bean的日期属性
  4. 支持HttpMessageConverters,可以方便返回json等数据类型,将java Bean直接返回成json数据
  5. 注册MessageCodesResolver,方便国际化及错误消息处理
  6. 支持静态index.html
  7. 自动使用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 效果

  1. 放了两个Filter:
    1. HiddenHttpMethodFilter;页面表单提交Rest请求。表单默认只能提交GET、POST请求,有了这个Filter就能提交PUT、DELETE请求了
      b. FormContentFilter: 表单内容Filter,配合HiddenHttpMethodFilter使用。默认GET(数据放URL后面)、POST(数据放请求体)请求可以携带数据,PUT、DELETE的请求体数据会被忽略,加了这个Filter后PUT和DELETE就能携带数据了
  2. 给容器中放了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就能配置底层行为

  1. WebMvcAutoConfiguration是一个自动配置类,它里面有一个EnableWebMvcConfiguration
  2. EnableWebMvcConfiguration继承于DelegatingWebMvcConfiguration,这两个都生效
  3. DelegatingWebMvcConfiguration利用DI把容器中所有WebMvcConfigurer注入进来
  4. 别人调用DelegatingWebMvcConfiguration的方法配置底层规则,而它调用所有WebMvcConfigurer的配置底层方法

http://www.kler.cn/news/109285.html

相关文章:

  • redis6.0源码分析:字典扩容与渐进式rehash
  • rust学习——智能指针Rc
  • 【论文复现:Active Learning via Local Structure Recontruction】
  • Qt6.5 CMake项目配置
  • nodejs+vue+elementui社区居民信息管理及数据分析与可视化系统设计
  • 微服务框架Consul--新手入门
  • 动静分离技术
  • centos ubantu IP一直变化,远程连接不上问题
  • C++二分查找算法的应用:最长递增子序列
  • 【贝叶斯回归】【第 1 部分】--pyro库应用
  • CentOS7安装配置MobaXterm使用换源处理虚拟机拍照备份与还原Linux常用命令
  • 【计算机网络】路由器的工作原理
  • Python beautifulsoup解析本地文件之基础语法
  • linux-磁盘应用
  • 决策树的优缺点
  • 磁盘管理(初始化,引导块,坏块管理,固态硬盘)
  • c# .net linux ImageSharp+FastDFS+Base64上传图片,压缩图片大小,图像处理dcoker中使用也可以
  • 汽车混动技术
  • docker 启动简单的开发环境(mysql, redis, etcd)
  • MySQL WITH AS及递归查询
  • ELASTICO-A Secure Sharding Protocol For Open Blockchains
  • 目标检测YOLO实战应用案例100讲-高速铁路供电安全检测监测系统图像智能识别(中)
  • 七层负载均衡 HAproxy
  • 由k8s升级慢引起的etcd性能不足的问题排查
  • Windows-Oracle11g 安装详解-含Navicate远程连接配置 -本地监听设置及更换navicate环境指向的oci.dll
  • 人工智能在疾病治疗中的应用:机遇与挑战
  • redis原理 主从同步和哨兵集群
  • 【蓝桥杯选拔赛真题05】C++超级素数 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析
  • VR数字党建:红色文化展厅和爱国主义教育线上线下联动
  • 2023秋《论文写作》课程总结