纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

Spring注解@EnableWebMvc使用 Spring注解@EnableWebMvc使用的坑点及解析

zxc123e   2021-09-14 我要评论
想了解Spring注解@EnableWebMvc使用的坑点及解析的相关内容吗zxc123e在本文为您仔细讲解Spring注解@EnableWebMvc使用的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Spring注解,@EnableWebMvc使用下面大家一起来学习吧

Spring注解@EnableWebMvc使用坑点

通过注解的方式来进行Spring4 MVC开发时我们都会在配置文件中加入<mvc:annotation-driven/>标签这个配置会自动注册了一个 RequestMappingHandlerMapping、一个RequestMappingHandlerAdapter、以及一个ExceptionHandlerExceptionResolver 以支持使用注解Controller的注解方法(如@RequestMapping、@ExceptionHandler)来处理request并开启一系列默认功能设置

<!-- 开启SpringMVC注解模式 -->
<!-- 提供一系列功能:数据绑定数字和日期format @NumberFormat, 
@DataTimeFormat,xml/json默认读写支持-->
<mvc:annotation-driven/>

如果没有配置<mvc:annotation-driven/>org.springframework.web.servlet.DispatcherServlet无法找到控制器并把请求分发到控制器

添加上<mvc:annotation-driven/>后请求会被相应的Controller处理然而这时访问静态资源可能就不好使了怎么办?一般可以使用 <mvc:default-servlet-handler />这个标签

<!-- 静态资源默认servlet配置
   1.加入对静态资源的处理:js/gif
   2.允许使用"/"做整体映射
-->
<mvc:default-servlet-handler />

所以这两个标签一般放在一起使用

在Spring Boot中使用@EnableWebMvc也可能遇到类似的问题@EnableWebMvc是使用注解方式快捷配置Spring Webmvc的一个注解

在使用时你可能会遇到以下问题:

  • Spring Boot在application文件中的配置失效
  • 在Spring Boot的自定义配置类加上@EnableWebMvc后发现自动配置的静态资源路径(classpath:/META/resources/classpath:/resources/classpath:/static/classpath:/public/)资源无法访问

通过查看@EnableWebMvc的源码可以发现该注解就是为了引入一个DelegatingWebMvcConfiguration 配置类而DelegatingWebMvcConfiguration又继承于WebMvcConfigurationSupport也就是说如果我们使用@EnableWebMvc就相当于导入了WebMvcConfigurationSupport类这个时候Spring Boot的自动装配就不会发生了我们能用的只有WebMvcConfigurationSupport提供的若干个配置其实不使用@EnableWebMvc注解也是可以实现配置Webmvc只需要将配置类继承于WebMvcConfigurationSupport类即可

  • 当使用@EnableWebMvc时加载的是WebMvcConfigurationSupport中的配置项
  • 当不使用@EnableWebMvc时使用的是WebMvcAutoConfiguration引入的配置项

查看一下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中的设置

WebMvcConfigurer 没有暴露高级设置如果需要高级设置 需要第二种方式继承WebMvcConfigurationSupport或者DelegatingWebMvcConfiguration例如:

   @Configuration
   @ComponentScan(basePackageClasses = { MyConfiguration.class })
   public class MyConfiguration extends WebMvcConfigurationSupport {
  
       @Override
      public void addFormatters(FormatterRegistry formatterRegistry) {
           formatterRegistry.addConverter(new MyConverter());
      }
  
      @Bean
      public 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 Configure
org.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
 */
@Deprecated
public 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;
@Configuration
public class MyWebConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/hello").setViewName("helloworld");
    }
}

When we access URL /hello then helloworld.jsp will run.

对于第二个问题如果使用@EnableWebMvc了那么就会自动覆盖了官方给出的/static, /public, META-INF/resources, /resources等存放静态资源的目录

而将静态资源定位于src/main/webapp当需要重新定义好资源所在目录时则需要主动添加上述的那个配置类来重写 addResourceHandlers方法

@Configuration
@EnableWebMvc
public 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类即可

以上为个人经验希望能给大家一个参考也希望大家多多支持


相关文章

猜您喜欢

  • Java Broadcast State Java 数据流之Broadcast State

    想了解Java 数据流之Broadcast State的相关内容吗Vicky_Tang在本文为您仔细讲解Java Broadcast State的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Java,Broadcast,State,Java,数据流下面大家一起来学习吧..
  • js圆盘时钟 js实现简单圆盘时钟

    想了解js实现简单圆盘时钟的相关内容吗山与小岛在本文为您仔细讲解js圆盘时钟的相关知识和一些Code实例欢迎阅读和指正我们先划重点:js,时钟下面大家一起来学习吧..

网友评论

Copyright 2020 www.sopisoft.net 【绿软下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式