非Spring Boot项目移除@EnableWebMvc仍运行,该注解作用何在?
关于Spring MVC中@EnableWebMvc的作用及依赖该注解的功能疑问
我有一个部署在Tomcat上的简单Spring MVC应用,并非Spring Boot项目,使用Spring 5.3.21版本。我想了解@EnableWebMvc的作用,移除该注解后项目仍能正常运行,但我看到资料说没有@EnableWebMvc的话@RequestMapping应该无法生效。请问还有哪些功能必须依赖@EnableWebMvc才能正常工作?
项目代码
1. RootConfig.java
package spittr.config; @Configuration @ComponentScan(basePackages = { "spittr" }) public class RootConfig { }
2. SpitterWebInitializer.java
package spittr.config; import spittr.web.WebConfig; public class SpitterWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { RootConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { WebConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } }
3. HomeController.java
package spittr.web; @Controller @RequestMapping("/") public class HomeController { @RequestMapping(method = GET) public String home(Model model) { return "home"; } }
4. WebConfig.java
package spittr.web; @Configuration @ComponentScan("spittr.web") public class WebConfig implements WebMvcConfigurer{ @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); return resolver; } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } }
5. home.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ page session="false" %> <html> <head> <title>Spitter</title> <link rel="stylesheet" type="text/css" href="<c:url value="/resources/style.css" />" > </head> <body> <h1>Welcome to Spitter</h1> <a href="<c:url value="/spittles" />">Spittles</a> | <a href="<c:url value="/spitter/register" />">Register</a> </body> </html>
问题解答
先解释你的项目无@EnableWebMvc仍能运行的原因:从Spring 4.3版本开始,只要配置类实现了WebMvcConfigurer接口(比如你的WebConfig),Spring会自动启用基础Spring MVC配置,其中就包括@RequestMapping的解析支持。你看到的老资料大概率针对的是更早的Spring版本,那时必须加@EnableWebMvc才能开启这些基础功能。
至于必须依赖@EnableWebMvc才能生效的功能,本质上它的作用是导入DelegatingWebMvcConfiguration,从而完整启用Spring MVC的全部高级特性,具体包括:
- 高级请求映射特性:带占位符的复杂URL模式匹配、基于请求头/参数的映射规则(
@RequestMapping的headers/params属性)、自定义请求映射处理器的自动注册 - 消息转换器自动配置:默认注册一系列
HttpMessageConverter,比如处理JSON的MappingJackson2HttpMessageConverter、处理XML的Jaxb2RootElementHttpMessageConverter等,无@EnableWebMvc时需手动注册才能处理JSON/XML格式的请求响应 - 内容协商机制:自动启用基于请求头、URL后缀的内容协商逻辑,比如根据
.json后缀自动返回JSON格式数据 - 静态资源高级处理:除了你手动开启的默认Servlet处理,还会自动配置
ResourceHttpRequestHandler,支持通过@RequestMapping访问静态资源、静态资源缓存控制等特性 - 拦截器、格式化器、验证器自动装配:默认注册
LocaleChangeInterceptor、ThemeChangeInterceptor等拦截器,ConversionService中的默认格式化器,以及JSR-303验证器的自动整合 - 视图解析增强:自动注册
ContentNegotiatingViewResolver,整合所有自定义视图解析器实现内容协商式视图解析 - 完整异常处理机制:自动配置
HandlerExceptionResolver系列实现,比如支持@ExceptionHandler注解的ExceptionHandlerExceptionResolver、处理@ResponseStatus注解异常的ResponseStatusExceptionResolver
简单说,仅实现WebMvcConfigurer只能获得基础MVC能力,而@EnableWebMvc是开启Spring MVC全部功能的开关,上述高级特性要么依赖它自动配置,要么你得手动编写大量代码来替代。
内容的提问来源于stack exchange,提问作者ericj
相关产品推荐
相关产品推荐

