SpringBoot学习笔记6——MVC配置原理

https://www.cnblogs.com/cxuanBlog/p/11179439.html
官网阅读
在进行项目编写前,我们还需要知道一个东西,就是SpringBoot对我们的SpringMVC还做了哪些配置,包括如何扩展,如何定制。

只有把这些都搞清楚了,我们在之后使用才会更加得心应手。途径一:源码分析,途径二:官方文档
在这里插入图片描述

我们来仔细对照,看一下它怎么实现的,它告诉我们SpringBoot已经帮我们自动配置好了SpringMVC,然后自动配置了哪些东西呢?

ContentNegotiatingViewResolver 内容协商视图解析器

自动配置了ViewResolver,就是我们之前学习的SpringMVC的视图解析器;

即根据方法的返回值取得视图对象(View),然后由视图对象决定如何渲染(转发,重定向)。

我们去看看这里的源码:我们找到 WebMvcAutoConfiguration , 然后搜索ContentNegotiatingViewResolver。找到如下方法!

在这里插入图片描述
我们可以点进这类看看!找到对应的解析视图的代码;
在这里插入图片描述
我们继续点进去看,他是怎么获得候选的视图的呢?

getCandidateViews中看到他是把所有的视图解析器拿来,进行while循环,挨个解析!

在这里插入图片描述

所以得出结论:ContentNegotiatingViewResolver 这个视图解析器就是用来组合所有的视图解析器的

我们再去研究下他的组合逻辑,看到有个属性viewResolvers,看看它是在哪里进行赋值的!
在这里插入图片描述
既然它是在容器中去找视图解析器,我们是否可以猜想,我们就可以去实现一个视图解析器了呢?

我们可以自己给容器中去添加一个视图解析器;这个类就会帮我们自动的将它组合进来;我们去实现一下

自定义 视图解析器

1、我们在我们的主程序中去写一个视图解析器来试试;
了解更多关于
@Configuration注解
package com.zhou.config;
@bean注解



import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;
//如果 ,你想 diy 一些定制化的功能,只要实现这个组件,然后将它交给springboot,springboot就会帮我们自动装配!
//扩展spring mvc ,dispatchServlet
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    
    



    //在一个方法上使用@Bean注解就表明这个方法需要交给Spring进行管理。
     @Bean
    public ViewResolver myViewResolver(){
    
    
        return new MyViewResolver();
    }


    //public interface ViewResolver 实现了视图解析器接口的类,我们就可以把他看作视图解析器
    //自定义一个自己的视图解析器MyViewResolver
    public static  class MyViewResolver implements ViewResolver{
    
    


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


}

在这里插入图片描述
2、怎么看我们自己写的视图解析器有没有起作用呢?

我们给 DispatcherServlet 中的 doDispatch方法 加个断点进行调试一下,因为所有的请求都会走到这个方法中
在这里插入图片描述

3、我们启动我们的项目,然后随便访问一个页面,看一下Debug信息;

找到this
在这里插入图片描述
所以说,我们如果想要使用自己定制化的东西,我们只需要给容器中添加这个组件就好了!剩下的事情SpringBoot就会帮我们做了!

格式化器和转换器

找到格式化转换器:

@Bean
@Override
public FormattingConversionService mvcConversionService() {
    
    
    // 拿到配置文件中的格式化规则
    WebConversionService conversionService = 
        new WebConversionService(this.mvcProperties.getDateFormat());
    addFormatters(conversionService);
    return conversionService;
}

点击去:

public String getDateFormat() {
    
    
    return this.dateFormat;
}

/**
* Date format to use. For instance, `dd/MM/yyyy`. 默认的
 */
 private String dateFormat;

可以看到在我们的Properties文件中,我们可以进行自动配置它!

如果配置了自己的格式化方式,就会注册到Bean中生效,我们可以在配置文件中配置日期格式化的规则:
在这里插入图片描述
在这里插入图片描述
其余的就不一一举例了,大家可以下去多研究探讨即可!
修改SpringBoot的默认配置
这么多的自动配置,原理都是一样的,通过这个WebMVC的自动配置原理分析,我们要学会一种学习方式,通过源码探究,得出结论;这个结论一定是属于自己的,而且一通百通。

SpringBoot的底层,大量用到了这些设计细节思想,所以,没事需要多阅读源码!得出结论;

SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),如果有就用用户配置的,如果没有就用自动配置的;

如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来!

扩展使用SpringMVC 官方文档如下:


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.

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

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

     @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    
    
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/index.html").setViewName("login");
        registry.addViewController("/main.html").setViewName("index");
    }
}

我们去浏览器访问一下:
在这里插入图片描述
确实也跳转过来了!所以说,我们要扩展SpringMVC,官方就推荐我们这么去使用,既保SpringBoot留所有的自动配置,也能用我们扩展的配置!

我们可以去分析一下原理:

1、WebMvcAutoConfiguration 是 SpringMVC的自动配置类,里面有一个类WebMvcAutoConfigurationAdapter

2、这个类上有一个注解,在做其他自动配置时会导入:@Import(EnableWebMvcConfiguration.class)

3、我们点进EnableWebMvcConfiguration这个类看一下,它继承了一个父类:DelegatingWebMvcConfiguration

这个父类中有这样一段代码:

public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
    
    
    private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
    
  // 从容器中获取所有的webmvcConfigurer
    @Autowired(required = false)
    public void setConfigurers(List<WebMvcConfigurer> configurers) {
    
    
        if (!CollectionUtils.isEmpty(configurers)) {
    
    
            this.configurers.addWebMvcConfigurers(configurers);
        }
    }
}

4、我们可以在这个类中去寻找一个我们刚才设置的viewController当做参考,发现它调用了一个


protected void addViewControllers(ViewControllerRegistry registry) {
    
    
    this.configurers.addViewControllers(registry);
}

5、我们点进去看一下


public void addViewControllers(ViewControllerRegistry registry) {
    
    
    Iterator var2 = this.delegates.iterator();

    while(var2.hasNext()) {
    
    
        // 将所有的WebMvcConfigurer相关配置来一起调用!包括我们自己配置的和Spring给我们配置的
        WebMvcConfigurer delegate = (WebMvcConfigurer)var2.next();
        delegate.addViewControllers(registry);
    }

}

所以得出结论:所有的WebMvcConfiguration都会被作用,不止Spring自己的配置类,我们自己的配置类当然也会被调用;

全面接管SpringMVC

官方文档:

If you want to take complete control of Spring MVC
you can add your own @Configuration annotated with @EnableWebMvc.

全面接管即:SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己去配置!

只需在我们的配置类中要加一个@EnableWebMvc。

我们看下如果我们全面接管了SpringMVC了,我们之前SpringBoot给我们配置的静态资源映射一定会无效,我们可以去测试一下;

不加注解之前,访问首页

我们发现所有的SpringMVC自动配置都失效了!回归到了最初的样子;

当然,我们开发中,不推荐使用全面接管SpringMVC

思考问题?为什么加了一个注解,自动配置就失效了!我们看下源码:

1、这里发现它是导入了一个类,我们可以继续进去看
在这里插入图片描述
在这里插入图片描述

2、它继承了一个父类 WebMvcConfigurationSupport
在这里插入图片描述
3、我们来回顾一下Webmvc自动配置类
在这里插入图片描述
总结一句话:@EnableWebMvc将WebMvcConfigurationSupport组件导入进来了;

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

在SpringBoot中会有非常多的扩展配置,只要看见了这个,我们就应该多留心注意~

猜你喜欢

转载自blog.csdn.net/qq_44788518/article/details/114868564