Day18 SpringBoot 4 MVC配置原理 扩展MVC
uwupu 啦啦啦啦啦

MVC配置原理

SpringBoot下的MVC自动配置

https://docs.spring.io/spring-boot/docs/2.7.3/reference/html/web.html#web.servlet.spring-mvc.auto-configuration

SpringBoot会默认进行配置以下内容:

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.//视图解析器
  • Support for serving static resources, including support for WebJars (covered later in this document).//静态资源 并支持webjars
  • Automatic registration of Converter, GenericConverter, and Formatter beans.//类型转换器,前端后端传值转换。Formatter可以进行格式转换,如日期转换。
  • Support for HttpMessageConverters (covered later in this document).//转换Http的请求和相应,如Java对象转换为Json。
  • Automatic registration of MessageCodesResolver (covered later in this document).//错误代码
  • Static index.html support. //主页自定义
  • Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).//将请求等封装在JavaBean中

如果想要保持SpringBootMvc的配置并且要添加更多的配置,

  • 可以自己新建一个WebMvc的配置类,
  • 实现WebMvcConfiguration接口并使用@Configuration注解,
  • 重写相应的方法即可。
  • 注意这里不用添加@EnableWebMvc注解。
1
2
3
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
}

示例:添加自定义视图解析器

在自定义的MVC配置类下添加一个视图解析器类和方法。

方法使用@Bean注解,将方法引入Spring。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

@Bean
public ViewResolver myViewResolver(){
return new MyViewResolver();
}

//自定义一个视图解析器
public static class MyViewResolver implements ViewResolver {
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
return null;
}
}
}

在ContentNegotiatingViewResolver类的getCandidateViews方法内部打断点可以获得目前加载的视图列表;

image

查看结果:

image

在候选视图解析器中出现自定义的视图解析器。

添加@EnableWebMvc,表示完全使用自定义的WebMvc自定义配置类

添加@EnableWebMvc,表示完全使用自定义的WebMvc自定义配置类。

原理

  1. 在WebMvcAutoConfiguration类中,有一个注解

    1
    @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

    表示如果出现WebMvcConfigurationSupport这个类,就不加载自动配置类

  2. @EnableWebMvc会加载WebMvcConfigurationSupport这个类,会导致WebMvcAutoConfiguration自动配置类失效,然后使用被注解的类作为WebMvc配置类。

    • @EnableWebMvc注解会导入类DelegatingWebMvcConfiguration;

      1
      2
      3
      4
      5
      6
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.TYPE)
      @Documented
      @Import(DelegatingWebMvcConfiguration.class)
      public @interface EnableWebMvc {
      }
    • DelegatingWebMvcConfiguration继承了WebMvcConfigurationSupport类。

      1
      public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {...}

扩展SpringMVC

使用几个示例表示如何去扩展SpringMVC。

Formatter

使用

  • 可以通过spring.mvc.format.date修改日期格式。

    • 默认格式:dd/MM/yyyy
  • 通过spring.mvc.format.dateTime修改日期时间格式。

    • 默认格式:yyyy-MM-dd HH:mm:ss
1
2
3
4
5
# 自定义配置日期格式化
spring:
mvc:
format:
date-time: dd-MM-yyyy

功能原理

在WebMvcAutoConfiguration自动配置类下有一个方法:

1
2
3
4
5
6
7
8
@Bean
@Override
public FormattingConversionService mvcConversionService() {
Format format = this.mvcProperties.getFormat();
WebConversionService conversionService = new WebConversionService(new DateTimeFormatters().dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
addFormatters(conversionService);
return conversionService;
}

这个方法引用了this.mvcProperties.getFormat();,mvcProperties指向一个WebMVCProperties对象。WebMVCProperties是SpringBoot下WebMvc的配置类。

1
private final WebMvcProperties mvcProperties;

进入WebMvcProperties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//省略后的WebMvcProperties
@ConfigurationProperties(prefix = "spring.mvc")//表示可以使用spring.mvc前缀配置类中内容。
public class WebMvcProperties {
...
private final Format format = new Format();
...

public Format getFormat() {
return this.format;
}
...
public static class Format {

/**
* Date format to use, for example 'dd/MM/yyyy'.
*/
private String date;//字符串格式

/**
* Time format to use, for example 'HH:mm:ss'.
*/
private String time;

/**
* Date-time format to use, for example 'yyyy-MM-dd HH:mm:ss'.
*/
private String dateTime;

public String getDate() {
return this.date;
}

public void setDate(String date) {
this.date = date;
}

public String getTime() {
return this.time;
}

public void setTime(String time) {
this.time = time;
}

public String getDateTime() {
return this.dateTime;
}

public void setDateTime(String dateTime) {
this.dateTime = dateTime;
}

}

...

}

得知:

  • 可以通过spring.mvc.format.date修改日期格式。

  • 通过spring.mvc.format.dateTime修改日期时间格式。

在自定义配置类中添加自定义视图解析器

1
2
3
4
5
6
7
8
9
10
//全面扩展 springmvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
WebMvcConfigurer.super.addViewControllers(registry);
registry.addViewController("/uwupu").setViewName("test");
}
}

registry.addViewController("/yn").setViewName("test");将/yn指向视图test。

结果:

image

其他

实现了视图解析器接口的类,这个类就是视图解析器。

 评论