11springboot的MVC配置原理

springboot的MVC配置原理

springboot现在是实现了mvc的自动配置,但是如果要修改/添加mvc的配置呢,比如上一篇的thymeleaf模板引擎,就自动配置了视图解析器,添加了前缀:classpath:/templates/和后缀:.html 。这样 访问方法的映射路径时,就不用添加文件的路径和后缀名,但是如果访问的文件不在 tmplates文件夹下或者是你想要访问的文件后缀不是html,那么应该怎么重新修改mvc的配置呢?接下来进入官方文档看mvc扩展/修改的说明,如下图:

image-20200901101955080

可以发现如果要扩展/修改 mvc配置 需要给自定义的mvc类添加 @Configuration注解 和 实现 WebMvcConfigurer接口,接下来用自定义视图解析器例子说明.

默认的视图解析器

springboot的自动装配的视图解析器是通过ContentNegotiatingViewResolver类(上图的第一个)来实现的,如果要自定义视图解析器,就得进入这个类去了解,如下图:

image-20200901113325980

可以发现该类实现了ViewResolver接口一般实现了视图解析器接口的类,都可以把它看作视图解析器,所以想要自定义视图解析器就需要实现该接口。ContentNegotiatingViewResolver类是springboot自动装配的视图解析器,而且该类实现视图解析器的接口,所以关键是视图解析器的接口,所以进入到ViewResolver接口可以发现里面包含一个resolveViewName()方法,该方法的作用是解析视图。接下来返回ContentNegotiatingViewResolver类中查看是怎么重写resolveViewName()方法的,如下图:

image-20200901115244570

核心是红框部分,getCandidateViews()方法是获取所有的候选视图,该方法里面是循环所有的视图解析器,然后通过视图解析器去获取所有视图并添加到视图候选区;getBestView()是从候选区中获取最好的视图,最后返回最好的视图,接下来实现自定义视图解析器。

自定义视图解析器

首先在自己创建的mvc配置类里面创建一个静态类去实现视图解析器的ViewResolver接口,然后重写里面的方法,如下:

/**
 * 扩展mvc,如果你想要diy一些定制化的功能,只要写这个组件,然后将它交给springboot,springboot会自动帮我们装配。
 */

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    
    //把视图解析器放入ioc容器中才会生效
    @Bean
    public ViewResolver myViewResolve(){
        return new MyViewResolve();
    }

    
    //自定义一个自己的视图解析器,并重写里面的方法
    public static class MyViewResolve implements ViewResolver{

        @Override
        public View resolveViewName(String viewName, Locale locale) throws Exception {
            return null;
        }
    }
}

然后测试一下,自己自定义的视图解析器是否生效了,如下:

所有请求都会经过DispatcherServlet类doDispatch()方法,所以在doDispatch()打断点,如下图:

image-20200901133415200

可以发现是可以识别到自定义的视图解析器。

springboot的MVC扩展

要想扩展mvc,根据官方文档说明,如下图:

image-20200902221250065

扩展mvc的配置类,必须实现WebMvcConfigurer接口和添加@Configuration注解 ,但是不能添加@EnableWebMvc注解,因为添加该注解会让springboot的mvc自动配置失效,如下:

image-20200902222138717

上图是springmvc自动配置的类,上面红框部分是一个条件,如果该WebMvcConfigurationSupport类不存在则当前自动配置生效,这个类和@EnableWebMvc注解有联系的,进入到@EnableWebMvc注解里面,如下:

image-20200902222730779

该注解导入了一个类,在进入到该类,如下:

image-20200902222757477

可以发现该类继承了WebMvcConfigurationSupport类,所以所以添加了@EnableWebMvc注解就相当于添加了WebMvcConfigurationSupport类,而mvc自动配置的类启动条件@ConditionalOnMissingBean中,是规定不能存在WebMvcConfigurationSupport类,存在则webMvc自动配置类失效。

所以官网 强调 自定义扩展mvc,不能添加@EnableWebMvc注解。

上面的自定义视图解析器就是mvc扩展的一个例子,接下来在使用一个例子说明,mvc是如何扩展的,如下:

/**
 * 扩展mvc
 */

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    //视图跳转
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //返回/abc会跳转到test.html
        registry.addViewController("/abc").setViewName("test");
    }
}

访问结果如下:

image-20200902224910942

访问abc映射路径,只有测试两字,而访问原来的test映射路径,多了一些值,是因为,该test映射路径里面添加了值。

该扩展是一个视图跳转,通常默认是浏览器访问是访问controller层的映射,但是这里添加了额外的映射,访问/abc会映射test.html视图。

总结

自定义配置类,必须实现WebMvcConfigurer接口和添加@Configuration注解 和属性类xxProperties,并且配置类要添加一些配置类的启动条件@ConditionalXX 和添加@EnableConfigurationProperties注解启动对应的属性类xxProperties。

posted @ 2020-09-02 22:58  HainChen  阅读(1216)  评论(0编辑  收藏  举报