zoukankan      html  css  js  c++  java
  • 07、SpringBoot的Web开发(MVC自动配置原理)

    官方文档 :https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration

    Spring MVC auto-configuration

    Spring Boot 自动配置好了SpringMVC

    以下是SpringBoot对SpringMVC的默认配置:(WebMvcAutoConfiguration)

    • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

      • 自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发、重定向))
      • ContentNegotiatingViewResolver:组合所有的视图解析器;
      • 如何定制:我们可以自己给容器中添加一个视图解析器;自动的将其组合进来;
    • Support for serving static resources, including support for WebJars。静态资源文件夹路径、webjars。

    • Static index.html support:静态首页访问。

    • 自动注册了Converter, GenericConverter, Formatter beans。

      • Converter:转换器;这就是我们网页提交数据到后台自动封装成为对象的东西,比如把"1"字符串自动转换为int类型
      • Formatter 格式化器;比如页面给我们了一个2020-5-10,它会给我们自动格式化为Date对象
    @Bean
    @ConditionalOnProperty(prefix = "spring.mvc", name = "date-format")//在文件中配置日期格式化的规则
    public Formatter<Date> dateFormatter() {
        return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件
    }
    

    自己添加的格式化器转换器,我们只需要放在容器中即可。

    • Support for HttpMessageConverters

      • HttpMessageConverter:SpringMVC用来转换Http请求和响应的;比如我们要把一个User对象转换为JSON字符串

      • HttpMessageConverters 是从容器中确定;获取所有的HttpMessageConverter;

        自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中(@Bean,@Component)

    • Automatic registration of MessageCodesResolver :定义错误代码生成规则。

    • Automatic use of a ConfigurableWebBindingInitializer bean。

      我们可以配置一个ConfigurableWebBindingInitializer来替换默认的;(添加到容器)

    org.springframework.boot.autoconfigure.web:web的所有自动场景;

    如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),则可以添加自己的@configuration类,类型为webmvcconfiguer,但不添加@EnableWebMvc。如果希望提供RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,则可以声明WebMVCregistrationAdapter实例来提供此类组件。

    扩展SpringMVC

        <mvc:view-controller path="/hello" view-name="success"/>
        <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="/hello"/>
                <bean></bean>
            </mvc:interceptor>
        </mvc:interceptors>
    

    编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型;不能标注@EnableWebMvc;

    既保留了所有的自动配置,也能用我们扩展的配置;

    我们要做的就是编写一个@Configuration注解类,并且类型要为WebMvcConfigurer,还不能标注@EnableWebMvc注解;我们去自己写一个;我们新建一个包叫config,写一个类MyMvcConfig;

    //应为类型要求为WebMvcConfigurer,所以我们实现其接口
    //可以使用自定义类扩展MVC的功能
    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer {
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            // 浏览器发送/test , 就会跳转到test页面;
            registry.addViewController("/test").setViewName("test");
        }
    }
    

    原理:

    1)WebMvcAutoConfiguration是SpringMVC的自动配置类。

    2)在做其他自动配置时会导入;@Import(EnableWebMvcConfiguration.class)

    @Configuration
    public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
        private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
    }
    //从容器中获取所有的WebMvcConfigurer
    @Autowired(required = false)
    public void setConfigurers(List<WebMvcConfigurer> configurers) {
        if (!CollectionUtils.isEmpty(configurers)) {
            this.configurers.addWebMvcConfigurers(configurers);
            //一个参考实现;将所有的WebMvcConfigurer相关配置都来一起调用;  
            @Override
            // public void addViewControllers(ViewControllerRegistry registry) {
            //    for (WebMvcConfigurer delegate : this.delegates) {
            //       delegate.addViewControllers(registry);
            //   }
        }
    }
    

    3)容器中所有的WebMvcConfigurer都会一起起作用;

    4)我们的配置类也会被调用;

    效果:SpringMVC的自动配置和我们的扩展配置都会起作用;

    全面接管SpringMVC

    如果您想完全控制Spring MVC,可以添加自己的@Configuration,并用@EnableWebMvc进行注释。

    就是SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己配置;所有的SpringMVC的自动配置都失效了。

    我们需要在配置类中添加@EnableWebMvc即可

    //使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
    @EnableWebMvc
    @Configuration
    public class MyMvcConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
           // super.addViewControllers(registry);
            //浏览器发送 /coydone 请求来到 success
            registry.addViewController("/coydone").setViewName("success");
        }
    }
    

    原理:为什么@EnableWebMvc自动配置就失效了?

    @EnableWebMvc的核心

    @Import(DelegatingWebMvcConfiguration.class)
    public @interface EnableWebMvc {
    
    @Configuration
    public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
    
    @Configuration
    @ConditionalOnWebApplication
    @ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
    		WebMvcConfigurerAdapter.class })
    //容器中没有这个组件的时候,这个自动配置类才生效
    @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
    @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
    		ValidationAutoConfiguration.class })
    public class WebMvcAutoConfiguration {}
    

    @EnableWebMvc将WebMvcConfigurationSupport组件导入进来;

    导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能;

    如何修改SpringBoot的默认配置

    模式:

    1)SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;

    2)在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置。

    3)在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置。

    coydone的博客
  • 相关阅读:
    RE
    【LeetCode】198. House Robber
    【LeetCode】053. Maximum Subarray
    【LeetCode】152. Maximum Product Subarray
    【LeetCode】238.Product of Array Except Self
    【LeetCode】042 Trapping Rain Water
    【LeetCode】011 Container With Most Water
    【LeetCode】004. Median of Two Sorted Arrays
    【LeetCode】454 4Sum II
    【LeetCode】259 3Sum Smaller
  • 原文地址:https://www.cnblogs.com/coydone/p/13821218.html
Copyright © 2011-2022 走看看