终于搞懂@EnableWebMvc,WebMvcConfigurer和WebMvcConfigurationSupport的机制了

Spring-Boot约定优于配置好是挺好的,但有时候也挺坑的,就比如我最近遇到的这个问题。因为项目需要加一个自定义的HandlerMethodReturnValueHandler来处理成统一的响应结果。网上一搜,有些博客会告诉你实现WebMvcConfigurer接口然后加上@Configuration和@EnbleWebMvc注解,有些博客又是另一种方式,让你直接继承WebMvcConfigurerAdapter或者继承WebMvcConfigurationSupport又或者继承DelegatingWebMvcConfiguration。各有各的说法,好像都能实现,又好像都会导致其他的问题,比如这个swagger突然就访问不了,或者Pageable突出就解析不了了等等。

这时候你可能会跟我一样,去瞅瞅这几个类的javadoc看看官方是怎么说的。然后你会发现,官方也是这么说的“大部分情况你只要实现WebMvcConfigurer接口你所需要实现的方法,然后加上@Configuration,然后其中一个类加上@EnbleWebMvc注解就可以了,当实现接口不能满足你的需求时确实是可以考虑继承WebMvcConfigurationSupport的”。那么问题到底出在什么地方呢?

问题就出在Spring-Boot的自动配置。前面的这些机制都是spring-webmvc这个jar提供的,如果没有自动配置,确实上面的方法都不会有问题(严格来说也不算问题,只是你不明白发生了什么而已)。而一旦你引入了spring-boot-autoconfigure,你就不能再按上面的说法去做了。

我来详细解释一下这里面的关系。首先spring-webmvc的机制是没有问题的,在不引入spring-boot-autoconfigure这个自动配置包的情况下,我们配置好swagger之后实际上是访问不到swagger的页面的,因为swagger本身以及我们自己都没有向spring注册相应的ResourceHandler。我们使用spring-boot之所以能访问到swagger-ui.html,是因为spring-boot-autoconfigure包中的WebMvcAutoConfiguration这个类。


image.png

上面这段代码来自WebMvcAutoConfiguration中的内部配置类WebMvcAutoConfigurationAdapter,就是它注册了/**的ResouceHandler让我们能够访问的classpath下面的swagger-ui.html。这一切本来都挺好的,问题的源头就出在WebMvcAutoConfiguration上面的一个注解:


image.png

意思是只有不存在WebMvcConfigurationSupport这个类型的bean时,这一大堆自动配置才会生效。而spring-webmvc推荐的使用@EnableWebMvc会自动引入DelegatingWebMvcConfiguration这个WebMvcConfigurationSupport的子类来加载所有实现了WebMvcConfigurer接口的Configuration,和直接继承WebMvcConfigurationSupport的效果一样都会导致自动配置失效。你说这能怪谁?怪spring-webmvc?人家单独开发写文档的时候又怎么会想到你autoconfigure会这么搞?怪autoconfigure?人家确实也是在尽可能让你既可以使用自动配置,又可以覆盖自动配置。只是你不会用而已,你只需要实现WebMvcConfigurer接口加上@Configuration就可以了,千万别加@EnableWebMvc。要怪只能怪你,没看源码罗!哈哈~~滑天下之大稽。我他喵搞了一整天才找到这个根源。

另外顺便提一嘴,别傻乎乎地真的去直接继承WebMvcConfigurationSupport,起码也应该是继承它的子类DelegatingWebMvcConfiguration,因为里面包含了加载所有实现了WebMvcConfigurer接口的Configuration。比如上面提到的Pageable失效就是因为直接继承WebMvcConfigurationSupport导致的SpringDataWebConfiguration这个配置没有被加载。
唉,难怪常看到“Spring Boot sucks”这样的字眼。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • springboot原理 未使用springboot时,怎样构建web项目(ssm架构的) 导入web及其配置,s...
    幻如常阅读 2,939评论 0 0
  • 1、简介 使用Spring Boot: (1)、创建Spring Boot应用,添加需要的模块; (2)、Spri...
    木石前盟Caychen阅读 4,982评论 0 6
  • 今天, 同事来找, 有个需求, 大概是这样子, 想用crontab shell方式跑我们现在的SpringBoot...
    it_true阅读 4,811评论 0 0
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 12,755评论 28 53
  • 人工智能是什么?什么是人工智能?人工智能是未来发展的必然趋势吗?以后人工智能技术真的能达到电影里机器人的智能水平吗...
    ZLLZ阅读 9,411评论 0 5

友情链接更多精彩内容