我们知道,在Spring Boot 2.0后用自己的的配置类继承WebMvcConfigurerAdapter时,idea会提示这个类已经过时了。

通常情况下我们会采用下面两种代替方案:

  • 实现WebMvcConfigurer
  • 继承WebMvcConfigurationSupport

但是继承WebMvcConfigurationSupport时发现会造成一些问题

在这之前,我们先看一下WebMvc自动配置类WebMvcAutoConfiguration的定义:

注意红框圈起来到这个关键语句:

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

看到这行可以明白,原来SpringBoot做了这个限制,只有当WebMvcConfigurationSupport类不存在的时候才会生效WebMvc自动化配置,WebMvc自动配置类中不仅定义了classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/等路径的映射,还定义了配置文件spring.mvc开头的配置信息等。

当 WebMvcAutoConfiguration 不生效时会导致以下几个问题:
1.WebMvcProperties 和 ResourceProperties 失效

因为两个配置类中的属性都在 WebMvcAutoConfiguration 中使用

当WebMvc自动配置失效(WebMvcAutoConfiguration自动化配置)时,会导致无法视图解析器无法解析并返回到对应的视图

解决方案:

1. 在SpringBoot1.X的版本中,我们可以继承自WebMvcConfigurerAdapter,覆盖想要实现的方法即可。

2. 但是在SpringBoot2.X的定义中,WebMvcConfigurerAdapter已经被定义为@Deprecated,我们来看一下源代码:

SpringBoot其实也已经告诉你WebMvcConfigurerAdapter自从Spring5.0版本开始已经不建议使用了,但是你可以实现WebMvcConfigurer并重写相关方法来达到类似的功能。

2.类路径上的 HttpMessageConverter 失效

如:StringHttpMessageConverterConfiguration、MappingJackson2HttpMessageConverter ,因为 HttpMessageConverters 中持有着所有HttpMessageConverter的实例, 在 WebMvcAutoConfigurationAdapter 中会注入 HttpMessageConverters ,因此当 WebMvcAutoConfigurationAdapter 不加载时,则会失效,间接的造成 spring.http.encoding.charset 与 spring.jackson.date-format 假象的失效。

如:StringHttpMessageConverter 会使用 spring.http.encoding.charset 配置, 默认编码为:ISO-8859-1

@Bean
@ConditionalOnMissingBean
public StringHttpMessageConverter stringHttpMessageConverter() {
StringHttpMessageConverter converter = new StringHttpMessageConverter(
this.encodingProperties.getCharset());
converter.setWriteAcceptCharset(false);
return converter;
}

解决方案
因为已知的配置类都已通过 @Bean 注册在容器中,那么我们可以在使用 WebMvcConfigurationSupport 时,通过 @Autowired 注入到配置类中,然后替换掉 WebMvcConfigurationSupport 默认的配置即可,如:

@Configuration
public class WebConfiguration extends WebMvcConfigurationSupport {
@Autowired
private StringHttpMessageConverter stringHttpMessageConverter;
@Autowired
private MappingJackson2HttpMessageConverter httpMessageConverter;
/**
* 添加转换器
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (int i = 0; i < converters.size(); i++) {
if (converters.get(i) instanceof StringHttpMessageConverter){
converters.set(i, stringHttpMessageConverter);
}
if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
converters.set(i, httpMessageConverter);
}
}
}
}

也可以根据需求来重新实现。

补充_

WebMvcConfigurer类代码分析:

从EnableWebMvcConfiguration配置类开始,当它注入时父类会注入Spring容器中所有的WebMvcConfigurer类

接着注入RequestMappingHandlerAdapter Bean 它会调用父类的requestMappingHandlerAdapter方法

这个时候获取配置,例如自定义了返回结果Handler, WebMvcConfigurerComposite会遍历调用WebMvcConfigurer实现类的

addReturnValueHandlers方法,会把自定义配置加载到默认的配置中

WebMvcConfigurer 与 WebMvcConfigurationSupport避坑指南的更多相关文章

  1. WebMvcConfigurationSupport 避坑指南

    通过返回WebMvcConfigurationSupport 的方式, 默认会覆盖 Spring boot的自动配置, 导致配置失效静态资源无法访问:但是在WebMvcConfigurationadp ...

  2. electron 编译 sqlite3避坑指南---尾部链接有已经编译成功的sqlite3

    electron 编译 sqlite3避坑指南(尾部链接有已经编译成功的sqlite3) sqlite很好用,不需要安装,使用electron开发桌面程序,sqlite自然是存储数据的不二之选,奈何编 ...

  3. CEF避坑指南(一)——下载并编译第一个示例

    CEF即Chromium Embedded Framework,Chrome浏览器嵌入式框架.它提供了接口供程序员们把Chrome放到自己的程序中.许多大型公司,如网易.腾讯都开始使用CEF进行前端开 ...

  4. Canal v1.1.4版本避坑指南

    前提 在忍耐了很久之后,忍不住爆发了,在掘金发了条沸点(下班时发的): 这是一个令人悲伤的故事,这条情感爆发的沸点好像被屏蔽了,另外小水渠(Canal意为水道.管道)上线一段时间,不出坑的时候风平浪静 ...

  5. Linux下Python3.6的安装及避坑指南

    Python3的安装 1.安装依赖环境 Python3在安装的过程中可能会用到各种依赖库,所以在正式安装Python3之前,需要将这些依赖库先行安装好. yum -y install zlib-dev ...

  6. Hive改表结构的两个坑|避坑指南

    Hive在大数据中可能是数据工程师使用的最多的组件,常见的数据仓库一般都是基于Hive搭建的,在使用Hive时候,遇到了两个奇怪的现象,今天给大家聊一下,以后遇到此类问题知道如何避坑! 坑一:改变字段 ...

  7. Harmony OS 开发避坑指南——源码下载和编译

    Harmony OS 开发避坑指南--源码下载和编译 本文介绍了如何下载鸿蒙系统源码,如何一次性配置可以编译三个目标平台(Hi3516,Hi3518和Hi3861)的编译环境,以及如何将源码编译为三个 ...

  8. 今天 1024,为了不 996,Lombok 用起来以及避坑指南

    Lombok简介.使用.工作原理.优缺点 Lombok 项目是一个 Java 库,它会自动插入编辑器和构建工具中,Lombok 提供了一组有用的注解,用来消除 Java 类中的大量样板代码. 目录 L ...

  9. Android连接远程数据库的避坑指南

    Android连接远程数据库的避坑指南 今天用Android Studio连接数据库时候,写了个测试连接的按钮,然后连接的时候报错了,报错信息: 2021-09-07 22:45:20.433 705 ...

随机推荐

  1. mariadb数据库简介

    mariadb(默认端口3306) 什么是数据库? 白话:用来存放数据的仓库,这个仓库只不过是按照一定的数据结构来组织. 数据库模型分为三种: 层次式数据库 网络式数据库 关系型数据库和非关系数据库 ...

  2. Java并发(基础知识)—— 创建、运行以及停止一个线程

    在计算机世界,当人们谈到并发时,它的意思是一系列的任务在计算机中同时执行.如果计算机有多个处理器或者多核处理器,那么这个同时性是真实发生的:如果计算机只有一个核心处理器那么就只是表面现象. 现代所有的 ...

  3. (转) httpclient对cookie的处理

    session的保持是通过cookie来维持的,所以如果用户有勾选X天内免登录,这个session 就X天内一直有效,就是通过这个cookie来维护.如果没选X天内免登录,基本上就本次才能保持sess ...

  4. BZOJ 4999 LCA树状数组差分维护DFS序

    Description 给一颗树,每个节点有个初始值 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x 2. Q i j x(0<=x<2 ...

  5. linux上开启和分析mysql慢查询日志

    本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群:   281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29Lo ...

  6. 超级大佬已提前布局AI域名,人工智能时代真的来临了?

    近日,郭盛华公司巨资收购的ai域名引起了业界深度关注,ai人工智能行业想必大家都熟悉不会陌生,但是ai域名你知道吗?了解域名行业的米友,对于ai域名肯定都熟悉,为什么今天小编要突然提到ai域名?因为a ...

  7. tp5.1中的命名规范

    类里边用驼峰(类名首字母大写,属性和方法首字母小写) 类名:User,UserType 类中的属性和方法:getUserName(),tableName,instance 参数.数据表和字段 用小写字 ...

  8. thinkphp一对多关系

    兹有用户表user和评论表comment 一对一 public function returnmany() { return $this->hasOne('commnet','uid','use ...

  9. JDBC与Hibernate的区别

    相同点: ◆两者都是JAVA的数据库操作中间件. ◆两者对于数据库进行直接操作的对象都不是线程安全的,都需要及时关闭. ◆两者都可以对数据库的更新操作进行显式的事务处理. 不同点: ◆使用的SQL语言 ...

  10. JAVA笔记21-数组

    一.数组内存分析 1.java中的数组是引用数据类型,必须分配在堆中,数组中每个元素相当于它的成员变量(默认值为0):但C中的数组可以分配在栈中.数组中的元素可以是基本类型,也可以是引用类型.如Str ...