WebMvcConfigurationSupport与WebMvcConfigurer的关系

  大家从网上及源码注释上查到的解释是,在spring中配置WebMvc时有两种方法,一种是继承WebMvcConfigurationSupport,重写里面相应的方法,还有一种是继承WebMvcConfigurer的子抽象类WebMvcConfigurerAdapter,也是重写里面相应的方法,但是需要在配置类上添加@EnableWebMvc注解。那这两个类直接是什么关系呢?
  细心的开发者会发现,WebMvcConfigurationSupport中那些子类可以重写的空方法在WebMvcConfigurer都有,这说明WebMvcConfigurer只是WebMvcConfigurationSupport的一个扩展类,它并没有扩展新功能,只是为让用户更方便安全的添加自定义配置,为什么说是安全呢?因为如果直接继承WebMvcConfigurationSupport,那么用户可以重写默认的配置,如果对原理不是很清楚地开发者不小心重写了默认的配置,springmvc可能相关功能就无法生效,是一种不安全的行为。但如果是继承WebMvcConfigurerAdapter,那么开发者是在默认配置的基础上添加自定义配置,相对来说更安全一些,只不过要多加一个@EnableWebMvc注解。从这个角度来说,最佳实践还是继承WebMvcConfigurerAdapter,如下

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加自定义拦截器
        registry.addInterceptor();
    }
}

网上说WebMvcConfigurerAdapter已经标记为过时,我目前用的是4.3.10版本还没有这个标识

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

  2. 为什么可以存在多个WebMvcConfigurer的实现?
      一般来讲一个应用中一个WebMvcConfigurer的已经足够,设计成收集多个是不是有些多余?从springboot的autoconfigure机制来看并不多余,反而更灵活,比如我要写一个mybatis的AutoConfiguration和JPA的AutoConfiguration,我就可以在不同的AutoConfiguration里面定义一个WebMvcConfigurer的实现,里面只配置与mybatis或JPA相关的配置,这样需要那个启用那个,不需要人工通过注释代码来转换mybatis和JPA,注意:在springboot下自定义的WebMvcConfigurer实现配置类上是不需要添加@EnableWebMvc的,因为springboot已经实例化了WebMvcConfigurationSupport,如果添加了该注解,默认的WebMvcConfigurationSupport配置类是不会生效的,也就是以用户定义的为主,一般建议还是不覆盖默认的好。

推荐阅读更多精彩内容