Spring注解@EnableWebMvc使用的坑点及解析
目录
- Spring注解@EnableWebMvc使用坑点
- @enablewebmvc注解有什么用途
Spring注解@EnableWebMvc使用坑点 通过注解的方式来进行Spring4 MVC开发时,我们都会在配置文件中加入
如果没有配置
添加上
所以这两个标签一般放在一起使用。
在Spring Boot中使用@EnableWebMvc也可能遇到类似的问题,@EnableWebMvc是使用注解方式快捷配置Spring Webmvc的一个注解。
在使用时你可能会遇到以下问题:
- Spring Boot在application文件中的配置失效
- 在Spring Boot的自定义配置类加上@EnableWebMvc后,发现自动配置的静态资源路径(classpath:/META/resources/,classpath:/resources/,classpath:/static/,classpath:/public/)资源无法访问。
- 当使用@EnableWebMvc时,加载的是WebMvcConfigurationSupport中的配置项。
- 当不使用@EnableWebMvc时,使用的是WebMvcAutoConfiguration引入的配置项。
@Configuration@ConditionalOnWebApplication(type = Type.SERVLET)@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,ValidationAutoConfiguration.class })public class WebMvcAutoConfiguration { ...}
可以看到自动配置类 WebMvcAutoConfiguration 上有条件注解
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
这个注解的意思是在项目类路径中缺少 WebMvcConfigurationSupport类型的bean时改自动配置类才会生效。
有时候我们需要自己定制一些项目的设置,可以有以下几种使用方式:
- @EnableWebMvc+extends WebMvcConfigurationAdapter,在扩展的类中重写父类的方法即可,这种方式会屏蔽springboot的@EnableAutoConfiguration中的设置
- extends WebMvcConfigurationSupport,在扩展的类中重写父类的方法即可,这种方式会屏蔽springboot的@EnableAutoConfiguration中的设置
- extends WebMvcConfigurationAdapter/WebMvcConfigurer,在扩展的类中重写父类的方法即可,这种方式依旧使用springboot的@EnableAutoConfiguration中的设置
@Configuration@ComponentScan(basePackageClasses = { MyConfiguration.class })public class MyConfiguration extends WebMvcConfigurationSupport {@Overridepublic void addFormatters(FormatterRegistry formatterRegistry) {formatterRegistry.addConverter(new MyConverter()); }@Beanpublic RequestMappingHandlerAdapter requestMappingHandlerAdapter() {// Create or delegate to "super" to create and// customize properties of RequestMappingHandlerAdapter}}
所以无论是使用@EnableWebMvc还是WebMvcConfigurationSupport,都会禁止Spring Boot的自动装配@EnableAutoConfiguration中的设置( 虽然禁止了Spring boot的自动装配,但是WebMvcConfigurationSupport本身,还是会注册一系列的MVC相关的bean的)。
@EnableAutoConfiguration是SpringBoot项目的启动类注解@SpringBootApplication的子元素,@EnableAutoConfiguration实际是导入EnableAutoConfigurationImportSelector和Registar两个类,主要功能是通过SpringFactoriesLoader.loadFactoryNames()导入jar下面配置文件META-INF/spring.factories。我们翻spring.factories,其中就包含WebMvc自动装配类:
...# Auto Configureorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\...
并且@EnableAutoConfiguration 注解,会自动读取 application.properties 或 application.yml 文件中的配置。因此想想前面提到的第一个问题就很明白了。
如果想要使用自动配置生效,同时又要使用部分spring mvc默认配置的话,比如增加 viewController ,则可以将自己的配置类可以继承 WebMvcConfigurerAdapter 这个类。不过在Spring5.0版本WebMvcConfigurerAdapter 后这个类被标记为@Deprecated了 。
* @author Rossen Stoyanchev * @since 3.1 * @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 */@Deprecatedpublic abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { ...}
Spring 5.0后要使用Java8,而在Java8中接口是可以有default方法的,所以这个类就没必要了。所以我们只需要在自定义配置类中直接实现 WebMvcConfigurer 接口就好了
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configurationpublic class MyWebConfig implements WebMvcConfigurer {@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/hello").setViewName("helloworld"); }}
When we access URL /hello then helloworld.jsp will run.【Spring注解@EnableWebMvc使用的坑点及解析】对于第二个问题,如果使用@EnableWebMvc了,那么就会自动覆盖了官方给出的/static, /public, META-INF/resources, /resources等存放静态资源的目录。
而将静态资源定位于src/main/webapp。当需要重新定义好资源所在目录时,则需要主动添加上述的那个配置类,来重写 addResourceHandlers方法。
@Configuration@EnableWebMvcpublic class MyWebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/public/"); }}
从上述可知在SpringBoot中大多数时我们并不需要使用@EnableWebMvc注解,来看下官方的一段说明:
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.说明:
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
Spring Boot 默认提供Spring MVC 自动配置,不需要使用@EnableWebMvc注解
如果需要配置MVC(拦截器、格式化、视图等) 请使用添加@Configuration并实现WebMvcConfigurer接口.不要添加@EnableWebMvc注解。
@EnableWebMvc 只能添加到一个@Configuration配置类上,用于导入Spring Web MVC configuration
最后,如果Spring Boot在classpath里看到有 spring webmvc 也会自动添加@EnableWebMvc。
Normally you would add @EnableWebMvc for a Spring MVC app, but Spring Boot adds it automatically when it sees spring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up a DispatcherServlet.http://spring.io/guides/gs/rest-service/
@enablewebmvc注解有什么用途 @EnableWebMvc是使用Java 注解快捷配置Spring Webmvc的一个注解。在使用该注解后配置一个继承于WebMvcConfigurerAdapter的配置类即可配置好Spring Webmvc。
通过查看@EnableWebMvc的源码,可以发现该注解就是为了引入一个DelegatingWebMvcConfiguration Java 配置类。并翻看DelegatingWebMvcConfiguration的源码会发现该类似继承于WebMvcConfigurationSupport的类。
其实不使用@EnableWebMvc注解也是可以实现配置Webmvc,只需要将配置类继承于WebMvcConfigurationSupport类即可
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
推荐阅读
- Activiti(一)SpringBoot2集成Activiti6
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- 2018-07-09|2018-07-09 Spring 的DBCP,c3p0
- spring|spring boot项目启动websocket
- 生活与游戏日记(第182篇)(〔成长瞬间〕关注解决问题2019.10)
- Spring|Spring Boot 整合 Activiti6.0.0
- Spring集成|Spring集成 Mina
- springboot使用redis缓存
- Spring|Spring 框架之 AOP 原理剖析已经出炉!!!预定的童鞋可以识别下发二维码去看了