重学SpringBoot3-EnableWebMvcConfiguration

重学SpringBoot3-EnableWebMvcConfiguration

CoderJia 42 2024-03-09

上一篇文章对 SpringMVC 重要配置类—— WebMvcAutoConfiguration 类进行了介绍,下面介绍下它引入的另外几个重要组件,它们分别是 EnableWebMvcConfiguration 类、WebMvcConfigurationSupport 类和 @EnableWebMvc注解,下图是它们的关系:

image-20240308163307865

1、EnableWebMvcConfiguration类

org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration

EnableWebMvcConfiguration 类是 Spring Framework 中的一个关键配置类,它类负责注册并配置 Spring MVC 的各种组件(管理着配置文件中 spring.web.xxx开头的配置项),例如:

  • 视图解析器(ViewResolvers):用于将视图名(如 "home")解析为实际的视图(如一个 JSP 文件或一个 Thymeleaf 模板)。
  • 消息转换器(MessageConverters):用于请求和响应的读写,例如将 Java 对象转换为 JSON 或 XML,反之亦然。
  • 静态资源处理(ResourceHandlers):用于提供对静态资源如图片、JS、CSS 文件的处理。
  • 拦截器(Interceptors)、参数解析器(ArgumentResolvers)和返回值处理器(ReturnValueHandlers)等。
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class })
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@ImportRuntimeHints(WebResourcesRuntimeHints.class)
public class WebMvcAutoConfiguration { 
    // 其他组件
  
	@Configuration(proxyBeanMethods = false)
    @EnableConfigurationProperties(WebProperties.class)
    public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {}
  
}

在日常开发中我们不经常直接与它交互,这个类扩展自 DelegatingWebMvcConfiguration,后者又扩展自 WebMvcConfigurationSupport

2、WebMvcConfigurationSupport类

org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport

WebMvcConfigurationSupport 是 Spring MVC 框架的核心配置支持类,提供了 Spring MVC 基础设施的背后配置。这个类通常在不使用 Spring Boot 自动配置时直接或间接被应用,特别是当开发者需要完全控制 Spring MVC 配置时。

@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {}

3、@EnableWebMvc注解

org.springframework.web.servlet.config.annotation.EnableWebMvc

该注解代码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

当你在配置类上使用 @EnableWebMvc 注解时,实际上是自己导入 DelegatingWebMvcConfiguration,它会引入 WebMvcConfigurationSupport 组件。这与 Spring Boot 自动配置 MVC 的方式不同(其实和 SpringBoot 自动配置互斥)。在不使用 Spring Boot,仅使用 Spring MVC 时,若想手动完全控制 MVC 配置(覆盖默认配置),就需要添加 @EnableWebMvc

所以使用 @EnableWebMvc 时,SpringBoot 的 WebMvcAutoConfiguration 都会失效。

4、EnableWebMvcConfiguration 和 WebMvcConfigurer的区别

  • 应用方式EnableWebMvcConfiguration 通过使用 @EnableWebMvc 注解间接应用,而 WebMvcConfigurer 是通过直接实现接口并重写其方法来应用。
  • 控制级别:使用 @EnableWebMvc(从而应用 EnableWebMvcConfiguration)意味着你想要完全控制 MVC 配置,覆盖 Spring Boot 的 MVC 自动配置。而实现 WebMvcConfigurer 允许在不失去自动配置的情况下定制和扩展 MVC 配置。
  • 使用场景EnableWebMvcConfiguration 主要用于非 Spring Boot 应用或者当需要完全控制 Spring MVC 配置时。WebMvcConfigurer 适用于需要定制 Spring Boot 自动配置的 Spring MVC 行为的情况。

5、自定义 Spring MVC 配置

即使使用了 @EnableWebMvc,你仍然可以通过实现 WebMvcConfigurer 接口来自定义 Spring MVC 的配置。这种方式允许你在保持默认配置的基础上进行添加或覆盖。

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    // 自定义配置,如添加视图解析器、消息转换器等
}

如果你使用的是 Spring Boot,通常不需要(也不建议)使用 @EnableWebMvc,因为 Spring Boot 为你提供了自动配置的 Spring MVC。但是,如果你需要完全控制 Spring MVC 的配置(这可能会禁用 Spring Boot 的自动配置),你可以添加 @EnableWebMvc 并提供你自己的配置。

请注意,EnableWebMvcConfiguration 通常是 Spring 内部使用的,开发者通过 @EnableWebMvc 注解和 WebMvcConfigurer 接口与 Spring MVC 的配置交互,而不是直接与 EnableWebMvcConfiguration 类交互。这是 Spring 如何设计它的组件和配置类,以帮助实现依赖注入和分离关注点。