WebMvcConfigurationSupport 和 WebMvcConfigurer 区别和同时使用产生的问题-解决

在Spring Boot 1.5版本都是靠重写WebMvcConfigurerAdapter的方法来添加自定义拦截器,消息转换器等。SpringBoot 2.0 后,该类被标记为@Deprecated(弃用)。

在Spring Boot 2.0后用自己的的配置类继承WebMvcConfigurerAdapter时,idea会提示这个类已经过时了。

通常情况下我们会采用下面两种代替方案:

  • 实现WebMvcConfigurer
  • 继承WebMvcConfigurationSupport

WebMvcConfigurer 

为什么WebMvcConfigurer实现要加@EnableWebMvc

  @EnableWebMvc注解类上导入了DelegatingWebMvcConfiguration类,该类是WebMvcConfigurationSupport的子类,该类除了实例化WebMvcConfigurationSupport实例以外,另一个作用就是收集BeanFactory中所有WebMvcConfigurer的实现,汇集到WebMvcConfigurerComposite中,在WebMvcConfigurationSupport实例化过程中会分别调用这些实现,将相应的实例传入这些实现中,供开发者在此基础上添加自定义的配置。这也就是在WebMvcConfigurerAdapter子类上要加@EnableWebMvc的原因,因为要先实例化WebMvcConfigurationSupport

注意:springboot下不需要添加@EnableWebMvc

对于springboot来讲,继承WebMvcConfigure无需再加@EnableWebMvc注解,因为springboot已经实例化了WebMvcConfigurationSupport,如果添加该注解,默认的WebMvcConfigurationSupport配置类是不会生效的,会以用户自定义的为主,一般建议还是不覆盖默认比较好。同时,继承WebMvcConfigurationSupport后,springboot的WebMvc自动配置失效(有可能导致视图解析器无法正常工作)。

### 为什么可以存在多个WebMvcConfigurer的实现?
   一般来讲一个应用中一个WebMvcConfigurer的已经足够,设计成收集多个是不是有些多余?从springboot的autoconfigure机制来看并不多余,反而更灵活,比如我要写一个mybatis的AutoConfiguration和JPA的AutoConfiguration,我就可以在不同的AutoConfiguration里面定义一个WebMvcConfigurer的实现,里面只配置与mybatis或JPA相关的配置,这样需要那个启用那个,不需要人工通过注释代码来转换mybatis和JPA,

WebMvcConfigurationSupport 

WebMvcConfigurationSupport中那些子类可以重写的空方法在WebMvcConfigurer都有,这说明WebMvcConfigurer只是WebMvcConfigurationSupport的一个扩展类,它并没有扩展新功能,只是为让用户更方便安全的添加自定义配置,为什么说是安全呢?

因为如果直接继承WebMvcConfigurationSupport,那么用户可以重写默认的配置,如果对原理不是很清楚地开发者不小心重写了默认的配置,springmvc可能相关功能就无法生效,是一种不安全的行为。

继承WebMvcConfigurationSupport时发现会造成一些问题

先看一下WebMvc自动配置类WebMvcAutoConfiguration的定义:

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

看到这行可以明白,原来SpringBoot做了这个限制, 只有当WebMvcConfigurationSupport类不存在的时候才会生效WebMvc自动化配置,WebMvc自动配置类中不仅定义了classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/等路径的映射,还定义了配置文件spring.mvc开头的配置信息等。

继承WebMvcConfigurationSupport会发现Spring Boot的WebMvc自动配置失效(WebMvcAutoConfiguration自动化配置)
如果想要使用自动配置生效,又要按自己的需要重写某些方法,比如增加拦截器。那么将配置类继承WebMvcConfigurationSupport改为实现WebMvcConfigurer接口即可。

总结一下:

1、WebMvcConfigurationSupport 和 WebMvcConfigurer都可以当作项目中的配置类,

WebMvcConfigurer是接口,WebMvcConfigurationSupport是个类

2、一个项目中只有一个WebMvcConfigurationSupport 类会生效

3、一个项目中可以有多个实现WebMvcConfigurer的类,并且都会生效

4、WebMvcConfigurationSupport 和 WebMvcConfigurer同时使用的时候,只有WebMvcConfigurationSupport中的配置会生效

不要同时使用 WebMvcConfigurationSupport和WebMvcConfigurer,推荐使用 WebMvcConfigurer。

猜你喜欢

转载自blog.csdn.net/zlfjavahome/article/details/131493065