美文网首页
spring-boot----关于web应用的自动配置和自定义支

spring-boot----关于web应用的自动配置和自定义支

作者: 不过意局bugyj | 来源:发表于2019-07-17 14:55 被阅读0次

    详细信息浏览官网

    29.1.1 Spring MVC Auto-configuration(以下翻译自官方文档)

    Spring Boot为Spring MVC提供了适用于大多数应用的自动配置支持。
    以下是对Spring MVC默认支持:

    • 自动配置了ContentNegotiatingViewResolver和BeanNameViewResolver两个视图解析器。
    • 支持静态资源,包括webjars(官方文档会有说明)
    • Converter, GenericConverter和 Formatter bean类的自动化装配。
    • 支持HttpMessageConverters(官方文档会有说明)。
    • MessageCodesResolver自动注册。
    • 支持index.html静态页面。
    • 支持自定义Favicon(网站图标)。
    • ConfigurableWebBindingInitializer自动使用

    如果你想保留Spring Boot MVC原有的功能而且还想添加额外MVC配置(interceptors,formatter,视图控制器view controller或者其他功能),你可以添加你自己@Configuration配置但没有@EnableWebMvc的WebMvcConfigurer类,如果你希望自定义RequestMappingHandlerMapping、RequestMappingHandlerAdapter或者ExceptionHandlerExceptionResolver对象。
    你可以声明一个 WebMvcRegistrationsAdapter 对象去提供这些组件。

    如果你想完全控制Spring MVC。你能添加自定义@Configuration和@EnableWebMvc注解的类。

    上述内容的理解

    1.视图解析器的自动配置

    ContentNegotiatingViewResolver类的作用是组合所有的视图解析器。
    从源码可以看出:

    //BeanFactoryUtils.beansOfTypeIncludingAncestors(this.obtainApplicationContext(), ViewResolver.class).values();
    //后续代码会将所有视图解析器对象放入一个ArrayList对象属性中。
    

    那么该如何自定义视图解析器呢?
    前面代码表示其是会从BeanFactory中获取视图解析器,所以我们完全可以自定义一个Java配置类,将自定义的一个试图解析对象放入spring容器即可。
    很简单,就不演示了。

    2.静态资源的支持包括index.html静态页面和favicon前面都学过,这里不总结了。

    3. formatter和converter

    • formatter即格式化对象,比如格式化日期类型。
    • converter即转换器类,比如讲众多属性转换为一个对象。
      两者的自动配置属于Spring MVC内容,无一例外的被包含在WebMvcConfiguration中,都是根据类型从spring容器中获取。
      代码一目了然:
    public class WebMvcConfiguration {
        public void addFormatters(FormatterRegistry registry) {
            Iterator var2 = this.getBeansOfType(Converter.class).iterator();
        
            while(var2.hasNext()) {
                Converter<?, ?> converter = (Converter)var2.next();
                registry.addConverter(converter);
            }
        
            var2 = this.getBeansOfType(GenericConverter.class).iterator();
        
            while(var2.hasNext()) {
                GenericConverter converter = (GenericConverter)var2.next();
                registry.addConverter(converter);
            }
        
            var2 = this.getBeansOfType(Formatter.class).iterator();
        
            while(var2.hasNext()) {
                Formatter<?> formatter = (Formatter)var2.next();
                registry.addFormatter(formatter);
            }
        
        }   
    }
    

    所以自定义一个formatter

    @Configuration
    public class DiyFormatterAutoConfiguration {
        
        private class DiyFormatter implements Formatter{}
        
        @Bean
        @ConditionalOnMissingBean({DiyFormatter.class})
        @ConditionalOnProperty{
            Prefix='spring.mvc';
            name={'diy-formatter'};
        }
        @AutoConfigureOrder(-2147483638)
        public DiyFormatter diyFormatter(){
            return new DiyFormatter();
        }
    }
    

    converter和GenericConverter同理。

    4. 支持HttpMessageConverters

    HttpMessageConverter就是一个策略接口, 用来将http请求转为某个对象, 或许将http响应转为指定类型的对象。

    public interface HttpMessageConverter<T> {
    
       //检测参数clazz指定的类型是否可以被该转换器读取 
        boolean canRead(Class<?> clazz, MediaType mediaType);
    
       //检测参数clazz指定的类型是否可以被该转换器写入
        boolean canWrite(Class<?> clazz, MediaType mediaType);
    
       //获取该转换器支持的媒体类型列表
        List<MediaType> getSupportedMediaTypes();
    
       //从输入信息中读取指定类型对象 
        T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
                throws IOException, HttpMessageNotReadableException;
    
       // 将指定的对象写入到输出
        void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
                throws IOException, HttpMessageNotWritableException;
    
    }
    

    其自动配置与上述formatter同理,具体略。

    5.后面的MessageCodeResolver定义错误代码生成规则的一个类,略

    6. ConfigurableWebBindingInitializer

    顾名思义,此类是用来初始化web数据绑定器的。
    而web数据绑定器是用来将前台传入的数据绑定到相关的bean中的,里面牵扯到的数据类型转换什么的也会用到前面提到的formatter等。

    public class WebMvcConfiguration {
        protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
            try {
                return (ConfigurableWebBindingInitializer)this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
            } catch (NoSuchBeanDefinitionException var2) {
                return super.getConfigurableWebBindingInitializer();
            }
        }
    }
    

    很清楚,如何自定义同上。

    7. 扩展Spring MVC

    扩展SpringMVC,我以添加view-controller为例:
    在SpringMVC项目下添加view-controller:

    <view-controller path="/hsw" view-name="success.html"/>
    

    在Spring boot中:

    @Configuration
    public class MyWebMvcConfiguration implements WebMvcConfigurer {
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/hsw").setViewName("success.html");
        }
    }
    

    新建一个类实现WebMvcConfigurer(视频中所说的是继承WebMvcConfigurer,但这个抽象类也是实现了WebMvcConfigurer接口,我猜这是因为jdk1.8支持了接口默认方法的原因吧!因为我们在实现接口时是选择性地实现方法的,而不是每一个方法都要实现,所以以前版本是会用抽象类实现默认方法实现。)然后实现相应的方法就行了。

    原理:1. WebMvcAutoConfiguration是SpringMVC的默认自动配置类。2. 自动配置类中有个静态内部类EnableWebMvcConfiguration,其父类DelegatingWebMvcConfiguratio有个方法·public void setConfigurers(List<WebMvcConfigurer> configurers) {能获取我们自定义实现的所有配置类。然后在静态内部类中将配置给添加到容器中。

    相关文章

      网友评论

          本文标题:spring-boot----关于web应用的自动配置和自定义支

          本文链接:https://www.haomeiwen.com/subject/xxwqlctx.html