【SpringBoot】10、MVC自动配置原理【狂神篇】

1、官方文档

在这里插入图片描述

Spring MVC Auto-configuration
// Spring Boot为Spring MVC提供了自动配置,它可以很好地与大多数应用程序一起工作。
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
// 自动配置在Spring默认设置的基础上添加了以下功能:
The auto-configuration adds the following features on top of Spring’s defaults:
// 包含视图解析器
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
// 支持静态资源文件夹的路径,以及webjars
Support for serving static resources, including support for WebJars 
// 自动注册了Converter:
// 转换器,这就是我们网页提交数据到后台自动封装成为对象的东西,比如把"1"字符串自动转换为int类型
// Formatter:【格式化器,比如页面给我们了一个2019-8-10,它会给我们自动格式化为Date对象】
Automatic registration of Converter, GenericConverter, and Formatter beans.
// HttpMessageConverters
// SpringMVC用来转换Http请求和响应的的,比如我们要把一个User对象转换为JSON字符串,可以去看官网文档解释;
Support for HttpMessageConverters (covered later in this document).
// 定义错误代码生成规则的
Automatic registration of MessageCodesResolver (covered later in this document).
// 首页定制
Static index.html support.
// 初始化数据绑定器:帮我们把请求数据绑定到JavaBean中!
Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

/*
如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),则可以添加自己的@configuration类,类型为webmvcconfiguer,但不添加@EnableWebMvc。如果希望提供
RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,则可以声明WebMVCregistrationAdapter实例来提供此类组件。
*/
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration 
(interceptors, formatters, view controllers, and other features), you can add your own 
@Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide 
custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or 
ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.

// 如果您想完全控制Spring MVC,可以添加自己的@Configuration,并用@EnableWebMvc进行注释。
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

2、ContentNegotiatingViewResolver

内容协商视图解析器

  • WebMvcAutoConfiguratio
@Configuration
...
public class WebMvcAutoConfiguration ... {
	...
    // 内部静态类
    @Configuration
    ...
    public static class WebMvcAutoConfigurationAdapter ...{
        // 获取视图解析器
        public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
            // 内容协商视图解析器
            ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
            resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));
            // ContentNegotiatingViewResolver使用所有其他视图解析器来定位视图,因此它应该具有较高的优先级
            resolver.setOrder(-2147483648);
            return resolver;
        }
    }    
}    
  • ContentNegotiatingViewResolver
public class ContentNegotiatingViewResolver ... {
    ...
        
    @Nullable // 参数可以为null
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        ...
        // 得到候选视图
        List<View> candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes);
        // 得到最佳视图
        View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs);
        ...
    }
    
    // 得到候选视图
    private List<View> getCandidateViews(String viewName, Locale locale, List<MediaType> requestedMediaTypes) throws Exception {
        List<View> candidateViews = new ArrayList();
        if (this.viewResolvers != null) {
            ...
            // 把所有的视图解析器拿来,进行while循环,挨个解析!
            Iterator var5 = this.viewResolvers.iterator();

            while(var5.hasNext()) {
                ...
            }
        }

        ...

        return candidateViews;
    }
}

总结:ContentNegotiatingViewResolver 这个视图解析器就是用来组合所有的视图解析器的

  • viewResolvers 属性
public class ContentNegotiatingViewResolver ... {
    @Nullable
    private List<ViewResolver> viewResolvers;
    
    //setViewResolvers(List<ViewResolver> viewResolvers)

    //getViewResolvers()
    
    protected void initServletContext(ServletContext servletContext) {
        // 从beanFactory工具中获取容器中的所有视图解析器
        // ViewRescolver.class 把所有的视图解析器组合起来
        Collection<ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.obtainApplicationContext(), ViewResolver.class).values();
        ViewResolver viewResolver;
        if (this.viewResolvers == null) {
            this.viewResolvers = new ArrayList(matchingBeans.size());
            Iterator var3 = matchingBeans.iterator();

            while(var3.hasNext()) {
                viewResolver = (ViewResolver)var3.next();
                if (this != viewResolver) {
                    this.viewResolvers.add(viewResolver);
                }
            }
        } else {
            // ...
        }

        AnnotationAwareOrderComparator.sort(this.viewResolvers);
        this.cnmFactoryBean.setServletContext(servletContext);
    }    
}    
  • 测试自定义视图解析器
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Bean // 注入spring
    public ViewResolver myViewResolver(){
        return new MyViewResolver();
    }

    // 内部静态类:自定义视图解析器
    public static class MyViewResolver implements ViewResolver{
        @Override
        public View resolveViewName(String viewName, Locale locale) throws Exception {
            return null;
        }
    }
}

在这里插入图片描述

在 DispatcherServlet 类中的 doDispatch() 方法上设置断点

在这里插入图片描述

Debug启动测试

在这里插入图片描述

总结:如果想要使用自己定制化的功能,只需要给容器中添加这个组件就好了!

3、转换器和格式化器

Converter

就是网页提交数据到后台自动封装成为对象的功能,比如把"1"字符串自动转换为int类型

Formatter

如日期格式

4、修改默认配置

  • 扩展SpringMVC

添加自己的 @configuration 类,类型为 webmvcconfiguer,但不添加 @EnableWebMvc,如果添加@EnableWebMvc ,自动配置将失效,就不是扩展,而是全面接管

自定义配置类是官方推荐的扩展方式

// 应为类型要求为WebMvcConfigurer,所以实现其接口
// 可以使用自定义类扩展MVC的功能
@Configuration
// @EnableWebMvc 
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 浏览器发送/test , 就会跳转到test页面;
        registry.addViewController("/test").setViewName("test");
    }
}
  • 全面接管SpringMVC

就是在自已的配置类中加上 @EnableWebMvc,让自动配置失效

这个注解的意思就是:容器中没有这个组件的时候,这个自动配置类才生效@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

当加上@EnableWebMvc时,容器中就存在了这个组件,自动配置类就不失效

不推荐使用全面接管SpringMVC

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

土味儿~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值