SpringMVC自动配置

原完整地址
springboot对springmvc做了哪些配置我们可以根据源码或者官方文档来看。(任何学习都是这样)
SpringBoot官方文档 官方文档关于做了哪些配置的内容如下

  1. Spring MVC Auto-configuration
  2. // Spring Boot为Spring MVC提供了自动配置,它可以很好地与大多数应用程序一起工作。
  3. Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
  4. // 自动配置在Spring默认设置的基础上添加了以下功能:
  5. The auto-configuration adds the following features on top of Spring’s defaults:
  6. // 包含视图解析器
  7. Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
  8. // 支持静态资源文件夹的路径,以及webjars
  9. Support for serving static resources, including support for WebJars
  10. // 自动注册了Converter:
  11. // 转换器,这就是我们网页提交数据到后台自动封装成为对象的东西,比如把"1"字符串自动转换为int类型
  12. // Formatter:【格式化器,比如页面给我们了一个2019-8-10,它会给我们自动格式化为Date对象】
  13. Automatic registration of Converter, GenericConverter, and Formatter beans.
  14. // HttpMessageConverters
  15. // SpringMVC用来转换Http请求和响应的的,比如我们要把一个User对象转换为JSON字符串,可以去看官网文档解释;
  16. Support for HttpMessageConverters (covered later in this document).
  17. // 定义错误代码生成规则的
  18. Automatic registration of MessageCodesResolver (covered later in this document).
  19. // 首页定制
  20. Static index.html support.
  21. // 图标定制
  22. Custom Favicon support (covered later in this document).
  23. // 初始化数据绑定器:帮我们把请求数据绑定到JavaBean中!
  24. Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).
  25. /*
  26. 如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),则可以添加自己
  27. 的@configuration类,类型为webmvcconfiguer,但不添加@EnableWebMvc。如果希望提供
  28. RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义
  29. 实例,则可以声明WebMVCregistrationAdapter实例来提供此类组件。
  30. */
  31. If you want to keep Spring Boot MVC features and you want to add additional MVC configuration
  32. (interceptors, formatters, view controllers, and other features), you can add your own
  33. @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide
  34. custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or
  35. ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.
  36. // 如果您想完全控制Spring MVC,可以添加自己的@Configuration,并用@EnableWebMvc进行注释。
  37. If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

扩展SpringMVC

39,40 怎么扩展springmvc的方法已经说了:只需要建一个类,添加@Configuration注解.但不添加@EnableWebMvc
一个webmvc类,我们应该写作接口。打开webmvcconfigurer,可以发现它是一个接口。那么我们实现它即可拥有mvc的功能。
实现视图解析器的类,便可以看作是一个视图解析器
使用快捷方法generate,在Override Method里面可以看到我们的自定义实现类继承了非常多的方法。
image.png
我们要什么功能,直接重写即可。而原来我们是实现。重写比实现更简单的。

  1. //扩展springMVC
  2. @Configuration
  3. public class MyMVC implements WebMvcConfigurer {
  4. @Bean //放到bean中。使我们这个自定义的springmvc添加到springboot。springboot会帮我们自动装配
  5. public ViewResolver myViewResolver(){
  6. return new MyViewResolver(); //返回视图解析器
  7. }
  8. //我们写一个静态内部类,视图解析器就需要实现ViewResolver接口
  9. return null;
  10. }
  11. }
  12. }

这里没有用到@EnableWebMvc。不知道为什么。该注解作用是类似import。该注解可以导入webmvc的配置

验证是否生效

我们给 DispatcherServlet 中的 doDispatch方法 加个断点进行调试一下,因为所有的请求都会走到这个方法中(该方法为springMVC的前置控制器,为SpringMVC的核心)
我们启动我们的项目,然后随便访问一个页面,看一下Debug信息;
找到this
Web开发4-SpringMVC自动配置 - 图2
找到视图解析器,我们看到我们自己定义的就在这里了;
Web开发4-SpringMVC自动配置 - 图3

完全控制SpringMVC

还是写一个WebMVC配置类,添加@Configuration注解标注该类是配置类。**并且添加**@EnableWebMvc
为什么扩展时不需要加@EnableWebMvc,而完全控制就要加呢

@EnableWebMvc

该注解就是导入了一个类:**DelegatingWebMvcConfiguration该类的作用是从容器中获取所有的**webmvcconfig

  1. @Import({DelegatingWebMvcConfiguration.class})
  2. public @interface EnableWebMvc { }

进入导入的类 public class DelegatingWebMvcConfiguration extendsWebMvcConfigurationSupport{// ......}
回顾WebMvcAutoConfiguration类,开头有这样一个注解
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
该注解表示没有WebMvcConfigurationSupport**这个类时下面的一系列自动配置代码才会生效
WebMvcConfigurationSupport只有SpringMVC最基本的功能**

  • 所以如果我们只是想增加小部分功能,就不要加@EnableWebMVC,否则全部自动配置都失效了
  • 我们不需要修改功能,只需要扩展即可。修改就意为着全部都要改 扩展则根据配置优先级,自动配置与手动配置共存

    默认配置与用户配置优先级

    SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),如果有就用用户配置的,如果没有就用自动配置的;
    如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来

    ContentNegotiatingViewResolver内容协商视图解析器

    自动配置了ViewResolver,就是我们之前学习的SpringMVC的视图解析器;
    即根据方法的返回值取得视图对象(View),然后由视图对象决定如何渲染(转发,重定向)。
    SpringMVC原理
    内容协商视图解析器实现与继承了多个类。其中就实现了ViewResolver 以前视图解析需要我们手动配置,现在默认走的templates目录

Formatter格式化转化器

原理

还是在WebMVCautoConfiguration找到Formatter相关的代码,找到的代码如下

  1. @Bean
  2. @Override
  3. public FormattingConversionService mvcConversionService() {
  4. // 拿到配置文件中的格式化规则
  5. WebConversionService conversionService =new WebConversionService(this.mvcProperties.getDateFormat());
  6. addFormatters(conversionService);
  7. return conversionService;
  8. }

第5行表示会从Properties中获取格式化规则(getDateFormat)
进入WebMVCProperties,有着getDateFormat方法的具体内容

  1. public String getDateFormat() {
  2. return this.dateFormat;
  3. }
  4. /**
  5. * Date format to use. For instance, `dd/MM/yyyy`. 默认的
  6. */
  7. private String dateFormat;

如果数据不符合默认的dd/MM/yyyy格式,就会报错。

自定义配置

spring.mvc.data-format=...比如我们希望日期为dd-MM-yyyy的格式,就可以自定义该规则
新版本该配置被修改废弃了
image.png

跳转(以下跳转方法均是SpringMVC的内容 )

跳转(官方推荐的跳转扩展方式)

需要实现WebMvcConfigurer类,重写addViewControllers方法。添加@Configuration,等价于xml配置。

  1. @Configuration //表示这是应该
  2. public class WebConfig implements WebMvcConfigurer{
  3. @Override
  4. public void addViewControllers(ViewControllerRegistry registry) {
  5. registry.addViewController("test").setViewName("emp/test");
  6. }
  7. }

等价于

  1. @Controller
  2. public class EmpContrller {
  3. @RequestMapping("test")
  4. public String test() {
  5. return "emp/test";
  6. }
  7. }