详解Spring|详解Spring Boot中如何自定义SpringMVC配置
目录
- 前言
- 一、SpringBoot 中 SpringMVC 配置概述
- 二、WebMvcConfigurerAdapter 抽象类
- 三、WebMvcConfigurer 接口
- 四、WebMvcConfigurationSupport 类-自定义配置
- 五、WebMvcAutoConfiguration 配置类 – 自动化配置
- 六、@EnableWebMvc 注解
- 七、总结
前言 在 Spring Boot 框架中只需要在项目中引入 spring-boot-starter-web 依赖,SpringMVC 的一整套东西就会自动给我们配置好;但是,真实的项目环境比较复杂,系统自带的配置不一定满足我们的需求,往往我们还需要结合实际情况自定义配置。
自定义配置就有讲究了,由于 Spring Boot 的版本变迁,加上这一块本身就有几个不同写法,容易搞混。
一、SpringBoot 中 SpringMVC 配置概述
首先我们需要明确,跟自定义 SpringMVC 相关的类和注解主要有如下四个:
- WebMvcConfigurerAdapter
- WebMvcConfigurer
- WebMvcConfigurationSupport
- @EnableWebMvc
二、WebMvcConfigurerAdapter 抽象类
【详解Spring|详解Spring Boot中如何自定义SpringMVC配置】我们先来看 WebMvcConfigurerAdapter,这个是在 Spring Boot 1.x 中我们自定义 SpringMVC 时继承的一个抽象类。
这个抽象类本身是实现了 WebMvcConfigurer 接口,然后抽象类里边都是空方法,我们来看一下这个类的声明:
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {//各种 SpringMVC 配置的方法}
再来看看这个类的注释:
/** * An implementation of {@link WebMvcConfigurer} with empty methods allowing * subclasses to override only the methods they're interested in. * @deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made * possible by a Java 8 baseline) and can be implemented directly without the * need for this adapter */
这段注释关于这个类说的很明白了。
同时我们也看到,从 Spring5 开始,由于我们要使用 Java8,而 Java8 中的接口允许存在 default 方法,因此官方建议我们直接实现 WebMvcConfigurer 接口,而不是继承 WebMvcConfigurerAdapter。
也就是说,在 Spring Boot 1.x 的时代,如果我们需要自定义 SpringMVC 配置,直接继承 WebMvcConfigurerAdapter 类即可。
三、WebMvcConfigurer 接口
如上所述,WebMvcConfigurer 是在 Spring Boot 2.x 中实现自定义配置的方案。
WebMvcConfigurer 是一个接口;接口中的方法和 WebMvcConfigurerAdapter 中定义的空方法其实一样,所以用法上来说,基本上没有差别。
从 Spring Boot 1.x 切换到 Spring Boot 2.x ,只需要把继承类改成实现接口即可。
四、WebMvcConfigurationSupport 类-自定义配置
在 Spring 框架中,可以通过 Spring 和 SpringMVC 的XML 配置文件设置MVC 框架;在 Spring Boot 中自定义 SpringMVC 配置时,可以通过继承 WebMvcConfigurationSupport 类来实现。
在 WebMvcConfigurationSupport 类中,提供了用 Java 配置 SpringMVC 所需要的所有方法。我们来看一下这个方法的摘要:
文章图片
WebMvcConfigurationSupport 类方法列表
有一点眼熟,可能有小伙伴发现了,这里的方法其实和前面两个类中的方法基本是一样的。
在这里首先大家需要明确的是,WebMvcConfigurationSupport 类本身是没有问题的,我们自定义 SpringMVC 的配置是可以通过继承 WebMvcConfigurationSupport 来实现的。
五、WebMvcAutoConfiguration 配置类 – 自动化配置
Spring Boot 中,SpringMVC 相关的自动化配置是在 WebMvcAutoConfiguration 配置类中实现的。
那么我们来看看这个配置类的生效条件:
@Configuration@ConditionalOnWebApplication(type = Type.SERVLET)@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,ValidationAutoConfiguration.class })public class WebMvcAutoConfiguration {}
我们从这个类的注解中可以看到,它的生效条件有一条,就是当不存在 WebMvcConfigurationSupport 的实例时,这个自动化配置才会生生效。
因此,如果我们在 Spring Boot 中自定义 SpringMVC 配置时选择了继承 WebMvcConfigurationSupport,就会导致 Spring Boot 中 SpringMVC 的自动化配置失效。
Spring Boot 给我们提供了很多自动化配置,很多时候当我们修改这些配置的时候,并不是要全盘否定 Spring Boot 提供的自动化配置。
我们可能只是针对某一个配置做出修改,其他的配置还是按照 Spring Boot 默认的自动化配置来。
而继承 WebMvcConfigurationSupport 来实现对 SpringMVC 的配置会导致所有的 SpringMVC 自动化配置失效,因此,一般情况下我们不选择这种方案。
六、@EnableWebMvc 注解
最后还有一个 @EnableWebMvc 注解,这个注解很好理解,它的作用就是启用 WebMvcConfigurationSupport。
我们来看看这个注解的定义:
/** * Adding this annotation to an {@code @Configuration} class imports the Spring MVC * configuration from {@link WebMvcConfigurationSupport}, e.g.:
可以看到,加了这个注解,就会自动导入 WebMvcConfigurationSupport。
所以在 Spring Boot 中,我们也不建议使用 @EnableWebMvc 注解,因为它一样会导致 Spring Boot 中的 SpringMVC 自动化配置失效。
七、总结
不知道上面的解释小伙伴有没有看懂?我再简单总结一下:
- Spring Boot 1.x 中,自定义 SpringMVC 配置可以通过继承 WebMvcConfigurerAdapter 来实现。
- Spring Boot 2.x 中,自定义 SpringMVC 配置可以通过实现 WebMvcConfigurer 接口来完成。
在纯 Java 配置的 SSM 环境中,如果我们要自定义 SpringMVC 配置,有两种办法:
- 第一种就是直接继承自 WebMvcConfigurationSupport 来完成 SpringMVC 配置
- 还有一种方案就是实现 WebMvcConfigurer 接口来完成自定义 SpringMVC 配置
换句话说,在纯 Java 配置的 SSM 中,如果你需要自定义 SpringMVC 配置,你离不开 WebMvcConfigurationSupport ,所以在这种情况下建议通过继承 WebMvcConfigurationSupport 来实现自动化配置。
推荐阅读
- Activiti(一)SpringBoot2集成Activiti6
- SpringBoot调用公共模块的自定义注解失效的解决
- Java|Java OpenCV图像处理之SIFT角点检测详解
- C语言浮点函数中的modf和fmod详解
- 解决SpringBoot引用别的模块无法注入的问题
- 2018-07-09|2018-07-09 Spring 的DBCP,c3p0
- 虚拟DOM-Diff算法详解
- LSTM网络层详解及其应用实例
- spring|spring boot项目启动websocket
- Spring|Spring Boot 整合 Activiti6.0.0