1

spring mvc 自动配置

spring boot 启动时会对 spring mvc 做自动配置,默认的配置功能在 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration 中进行了说明。有以下功能:

  • 自动注册视图解析器 ContentNegotiatingViewResolverBeanNameViewResolver

    • ContentNegotiatingViewResolver:组合容器中不同ViewResovler
    • BeanNameViewResolver:根据返回的视图名称去找对应的视图,比如controller中方法返回的视图名称。
    • 如何自定义一个视图解析器?
      可以给容器中添加一个视图解析器,spring boot会自动的将其组合进来

      @Configuration
      public class MyViewConfig {
      
          @Bean
          public ViewResolver myView() {
              return new MyViewResolver();
          }
      
         
          private class MyViewResolver implements ViewResolver {
      
              @Nullable
              @Override
              public View resolveViewName(String viewName, Locale locale)    throws Exception {
                  System.out.println("----------------> my view resolver");
                  return null;
              }
          }
      }

      通过在DispatcherServlet类中的doDispatch方法上断点可以查看容器中已经注入了我们自定义的视图解析器:
      图片描述
        

  • 支持对静态资源
  • 自动注册ConverterGenericConverterFormatter

    • ConverterGenericConverter : 对象参数转换器,把页面提交的文本参数转换为对象属性
    • Formatter :日期格式化器
  • 支持 HttpMessageConverters : spring mvc 中用来转换 http 请求和响应的。比如可以把一个对象转化为 json 格式的
  • 自动注册MessageCodesResolver: 定义错误代码响应规则的,默认规则可参考DefaultMessageCodesResolver
  • 支持静态欢迎首页index.html
  • 支持自定义 favicon 图标
  • 自动使用ConfigurableWebBindingInitializer : 初始化 WebDataBinder数据绑定器

扩展 spring mvc

有时候我需要保持保持 spring boot 对 spring mvc 的支持,同时会要求使用 spring mvc 的其他功能,比如拦截器功能,需要怎么办呢?

  • 我们的做法是给容器中添加一个自己的配置类(@Configuration),配置类的类型是WebMvcConfigurer,同时配置类不能被@EnableWebMvc注解注释。
/**
 * 扩展 spring mvc 功能
 */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/success").setViewName("success");
    }
}

全面控制 spring mvc

spring boot 对 spring mvc 的自动配置功能全部失效,spring mvc 的原始的功能都能够使用。需要我们做的是自定义的 spring mvc 配置类上添加注解 @EnableWebMvc即可。

@Configuration
@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/success").setViewName("success");
    }
}
  • 为什么 @EnableWebMvc注解会实现此功能呢?其原理如下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

可以看到@EnableWebMvc注解实现是导入了配置类DelegatingWebMvcConfiguration

@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
}

而该配置类继承了WebMvcConfigurationSupport,此时我们并没有发现什么特别之处,当你再观察 spring mvc 的配置类WebMvcAutoConfiguration时,发现该配置类中导入了WebMvcConfigurationSupport

@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
//容器中没有这个组件的时候,spring mvc的自动配置类才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
        TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
}

@EnableWebMvcWebMvcConfigurationSupport组件导入到容器中,而WebMvcConfigurationSupport只是支持 spring mvc 的最基本功能


一只小小鸟
144 声望25 粉丝

如何做一个深层次的思考者,从简单开始、从记录开始。