• spring boot springMVC扩展配置 。WebMvcConfigurer ,WebMvcConfigurerAdapter


    摘要:

      在spring boot中 MVC这部分也有默认自动配置,也就是说我们不用做任何配置,那么也是OK的,这个配置类就是 WebMvcAutoConfiguration,但是也时候我们想设置自己的springMvc配置怎么办呢 。我们也可以写个自己的配置类,继承 WebMvcConfigurer 重写需要的配置方法 。在spring boot 早期是继承WebMvcConfigurerAdapter ,但是高版已标上注解@Deprecated,注意:在配置类中不要标注:@EnableWebMvc,否则,spring boot的配置全部失效,只留自己扩展配置。

    示例:

    这里已高版为主 继承WebMvcConfigurer,WebMvcConfigurer 接口中的方法都是默认的方法,可以覆盖,也可以不实现 ,加一个视图解析配置 ,解析success请求路劲,返回success页面。如下代码:

    @Configuration
    public class MyMvcConfig Implements WebMvcConfigurer {
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
           // super.addViewControllers(registry);
            //浏览器发送 /success请求来到 success
            registry.addViewController("/success").setViewName("success");
        }
    }
     

    代码浅析:

    1.首先我们来看看WebMvcAutoConfiguration这个配置类,这个配置了有首页的默认路劲,还有一些静态资源路劲,而这些方法在它的一个内部类中,如下代码(删除了部分代码):

    
    
    @Configuration
    @ConditionalOnWebApplication(
        type = Type.SERVLET
    )
    @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
    @ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
    @AutoConfigureOrder(-2147483638)
    @AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
    public class WebMvcAutoConfiguration {
        ....//省略部分代码
        @Configuration
        @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}) // 导入了EnableWebMvcConfiguration这个类 addResourceHandlers方法
        @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})
        @Order(0)
        public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware {
           
        ...//省略部分代码
            public void addResourceHandlers(ResourceHandlerRegistry registry) {//实现WebMvcConfigurer 这个类的
                if(!this.resourceProperties.isAddMappings()) {
                    logger.debug("Default resource handling disabled");
                } else {
                    Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
                    CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
                    if(!registry.hasMappingForPattern("/webjars/**")) {
                        this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                    }
    
                    String staticPathPattern = this.mvcProperties.getStaticPathPattern();
                    if(!registry.hasMappingForPattern(staticPathPattern)) {
                        this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                    }
    
                }
            }
    
    }
    可以看到,内部类 WebMvcAutoConfigurationAdapter 标记 @Configuration,并导入另一个内部类 @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}),我们看下这个类,如下代码:
    @Configuration
        public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
            private final WebMvcProperties mvcProperties;
            private final ListableBeanFactory beanFactory;
            private final WebMvcRegistrations mvcRegistrations;
         ...// 省略
    }
    重点在它的父类, DelegatingWebMvcConfiguration  代码如下 (写了几个案列方法,其他代码省略。)。
    @Configuration
    public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
        private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
    
         ...//省略
        /**
         * 从容器中拿到所有 WebMvcConfigurer 的实现类。遍历添加到  configurers 
         * [required description]
         * @type {[type]}
         */
        @Autowired( required = false ) // 自动装配
        public void setConfigurers(List<WebMvcConfigurer> configurers) {
            if(!CollectionUtils.isEmpty(configurers)) {
                this.configurers.addWebMvcConfigurers(configurers);
            }
    
        }
        ...//省略
        /**
         * 当调用addResourceHandlers 时 ,调用的 成员configurers的 addResourceHandlers
         * [addResourceHandlers description]
         * @param {[type]} ResourceHandlerRegistry registry [description]
         */
        protected void addResourceHandlers(ResourceHandlerRegistry registry) {
            this.configurers.addResourceHandlers(registry);
        }
        ...//省略
    }
    来看看 WebMvcConfigurerComposite 的 addResourceHandlers的方法做了什么 :
    class WebMvcConfigurerComposite implements WebMvcConfigurer {
    
        private final List<WebMvcConfigurer> delegates = new ArrayList<WebMvcConfigurer>();
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) { // 遍历 把 所有WebMvcConfigurer的 addViewControllers方法调用一遍
            for (WebMvcConfigurer delegate : this.delegates) {
                delegate.addViewControllers(registry);
            }
        }
    }
    看到这里我们知道 ,不管是spring boot中实现的 WebMvcConfigurer 类,还是我们自己实现 WebMvcConfigurer ,只要我们把实现类注入到容器中,就会被 注入 WebMvcConfigurerComposite 这个类成员变量 delegates中
    。而 WebMvcConfigurerComposite 有是实现了 WebMvcConfigurer  。当调用 WebMvcConfigurer中 xxx方法的,就会遍历 delegates 中所有 WebMvcConfigurer  的方法xxx 。那我们的扩展配置
    MyMvcConfig 也就被调用了。


  • 相关阅读:
    页面跳转
    获取gridview 某列的值
    C#日期格式化的几种处理方法(转)
    asp.net 退出 按钮
    asp.net控件大全(一)
    导出Excel
    DropDownList的二级联动 (SqlDataSource实现和SQL 绑定实现)
    asp.net控件大全(二)
    如何让Gridview在没有数据的时候显示表头(asp.net)
    自定义日期格式
  • 原文地址:https://www.cnblogs.com/jonrain0625/p/11299810.html
Copyright © 2020-2023  润新知