Spring 全家桶之 Spring Boot 2.6.4(五)- WebMvcAutoConfiguration(Part C)

三、Spring Boot Web MVC 自动配置

Spring Boot 官方文档 Web 模块 的自动配置说明

Spring MVC Auto-configuration

Spring Boot 已经自动配置好了Spring MVC,可以使用Web Starter快速创建启动并运行。

Spring Boot 官方文档列出了以下这些关于MVC的配置

Spring Boot provides auto-configuration for Spring MVC that works well with most applications.

The auto-configuration adds the following features on top of Spring’s defaults:

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
  • Support for serving static resources, including support for WebJars (covered later in this document).
  • Automatic registration of ConverterGenericConverter, and Formatter beans.
  • Support for HttpMessageConverters (covered later in this document).
  • Automatic registration of MessageCodesResolver (covered later in this document).
  • Static index.html support.
  • Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

视图解析器

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans. 自动配置了视图解析器,视图解析器的作用是根据方法的返回值得到视图对象,视图对象再决定是否需要转发或者重定向。

视图解析器源码分析,入口是org.springframework.boot.autoconfigure.web.servlet包下的 自动配置类WebMvcAutoConfiguration,所有MVC的自动配置都在该类中,该类中包含了三个返回视图解析器resolver的方法,除了一个默认的defaultViewResolver方法外,另外两个就是自动配置的ContentNegotiatingViewResolver and BeanNameViewResolver

查看ContentNegotiatingViewResolver的resolveViewName方法是如何解析视图的

resolveViewName方法中通过getCandidateViews获取视图并保存在一个View的List中。

getCandidateViews方法会遍历所有的视图解析器来解析视图,将解析出来的视图保存到列表中

ContentNegotiatingViewResolver类的作用就是组合所有视图解析器解析视图。

ContentNegotiatingViewResolver先new了一个保存视图解析器的列表

调用视图解析器的初始化方法,通过BeanFactoryUtils从容其中获取所有的视图解析器保存在集合中

这样的话我们就可以自己给容器中添加一个视图解析器,自动的加进ContentNegotiatingViewResolver视图解析器的列表中

自定义视图解析器实现

public class LilithViewResolver implements ViewResolver {

    @Override
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        System.out.println("自定义的视图解析器LilithViewResolver");
        return null;
    }
}

通过配置类,将自定义的视图解析器注册到Spring容器中

@Configuration
public class ViewResolverConfig {

    // 将自定义的视图解析器注册到Spring容器中
    @Bean
    public ViewResolver lilithViewResolver(){
        return new LilithViewResolver();
    }
}

debug查看容器中是否在视图解析器的列表中,在doDispatch方法上打断点

根据Debug的信息来看,自定义的视图解析器已经被添加到视图解析器的列表中了

静态资源配置

静态资源的配置原理和使用可以参考 Spring 全家桶之 Spring Boot 2.6.4(五)- Web Develop(Part A)中的 Spring Boot对静态资源的映射规则 部分

自动注册Converter和Formatter格式化器

  • Automatic registration of ConverterGenericConverter, and Formatter beans.

类型转换器的作用是将前端请求中的String类型的数据转化成基本数据类型或者自定义对象;Formatter格式化的作用是将String时间转换成Date类型

自动配置类往容器中添加了一个组件FormattingConversionService,这个组件就包含了Converter功能和Formatter功能。

自定义格式转换器

首先定义一个注解@BoolFormat

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER})
public @interface BooleanFormat {

}

接着定义一个转换器类BooleanFormatter,继承Formatter接口,实现格式转换功能,并将该类注册到容器中,该类会将values数组中的值全部转换true,数组之外的为false。

@Component
public class BooleanFormatter implements Formatter<Boolean> {

    private final String[] values = {"是", "YES", "Y", "yes", "Yes", "ok", "OK", "Ok" , "好", "哦了"};

    @Override
    public Boolean parse(String text, Locale locale){

        return Arrays.asList(values).contains(text);
    }

    @Override
    public String print(Boolean object, Locale locale) {

        return object ? "true" : "false";
    }
}

再定义一个工厂类LilithBooleanFormatterFactory,继承AnnotationFormatterFactory

@Component
public class LilithBooleanFormatterFactory implements AnnotationFormatterFactory<BooleanFormat> {

    @Resource
    private BooleanFormatter booleanFormatter;

    @Override
    public Set<Class<?>> getFieldTypes() {
        Set<Class<?>> set=new HashSet<>();
        set.add(Boolean.class);
        return set;
    }

    @Override
    public Parser<?> getParser(BooleanFormat annotation, Class<?> fieldType) {
        return booleanFormatter;
    }

    @Override
    public Printer<?> getPrinter(BooleanFormat annotation, Class<?> fieldType) {
        return booleanFormatter;
    }
}

新建一个BoolController测试格式转换器是否能正常工作

@RestController
public class BoolController {

    @RequestMapping("/bool")
    public String hallo(@BooleanFormat Boolean value){

        return value.toString();
    }
}

重启应用

测试values数组以外的值,传入ooook

返回false

支持HTTP消息转换器

Spring MVC uses the HttpMessageConverter interface to convert HTTP requests and responses.

Spring MVC 使用HttpMessageConverter来转换HTTP请求和响应

官方文档 自定义HttpMessageConverter

自定义HttpMessageConverter的方式与自定义ViewResolver的方式一样,只需要将自定义的HttpMessageConverter加入容器中即可。

Spring Boot是如何自动配置HttpMessageConverter的?

WebMvcAutoConfiguration自动配置类中有一个WebMvcAutoConfigurationAdapter自动配置适配器,这个类的有参构造方法中导入了HttpMessageConverter

HttpMessageConverter实现了Iterable<HttpMessageConverter<?>> 接口

从容器中获取所有的HttpMessageConverter然后添加到自动配置类中

自动注册 MessageCodesResolver

Spring MVC has a strategy for generating error codes for rendering error messages from binding errors: MessageCodesResolver. If you set the spring.mvc.message-codes-resolver-format property PREFIX_ERROR_CODE or POSTFIX_ERROR_CODE, Spring Boot creates one for you (see the enumeration in DefaultMessageCodesResolver.Format).

主要是用来定义错误代码生成规则的

MessageCodeResolver在自动配置类中的配置方式

欢迎页配置

  • Static index.html support. 欢迎页的配置原理和使用可以参考 Spring 全家桶之 Spring Boot 2.6.4(五)- Web Develop(Part A)中的 Spring Boot 欢迎页 部分

自动使用 ConfigurableWebBindingInitializer

自动配置类中关于ConfigurableWebBindingInitializer的定义方式。可以自定义一个ConfigurableWebBindingInitializer来替换默认的。

getConfigurableWebBindingInitializer方法会首先从容器中获取ConfigurableWebBindingInitializer,如果找不到就会调用父类的getConfigurableWebBindingInitializer方法

父类中这个方法就是初始化所有的WebDataBinder,WebDataBinder的作用就是将请求数据转换成为Java Bean

initBinder就是初始化WebDataBinder的方法

org.springframework.boot.autoconfigure.web.servlet. DispatcherServletAutoConfiguration包含了Web模块所有的自动配置。

本站文章资源均来源自网络,除非特别声明,否则均不代表站方观点,并仅供查阅,不作为任何参考依据!
如有侵权请及时跟我们联系,本站将及时删除!
如遇版权问题,请查看 本站版权声明
THE END
分享
二维码
海报
Spring 全家桶之 Spring Boot 2.6.4(五)- WebMvcAutoConfiguration(Part C)
Spring Boot 已经自动配置好了Spring MVC,可以使用Web Starter快速创建启动并运行。
<<上一篇
下一篇>>