SpringBoot学习笔记(五)

本文主要介绍SpringBoot:MVC自动配置原理、转换器和格式化器和静态资源处理

一、SpringBoot:MVC自动配置原理

SpringBoot对我们的SpringMVC还做了哪些配置,包括如何扩展,如何定制。

我们能用到的途径:1.阅读源码;2.官方文档

image

#Spring-MVC自动配置
Spring MVC Auto-configuration

#springboot为springmvc提供了自动配置,可以很好地用于大多数应用程序。
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:

    #包含ContentNegotingViewResolver和BeanNameViewResolver bean。
    Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

    #对服务静态资源的支持,包括对webjar的支持(本文后面将介绍)。
    Support for serving static resources, including support for WebJars (covered later in this document)).

    #自动注册转换器、GenericConverter和格式化程序bean。
    Automatic registration of Converter, GenericConverter, and Formatter beans.

    #对HttpMessageConverters的支持(本文后面将介绍)。
    Support for HttpMessageConverters (covered later in this document).

    #MessageCodesResolver的自动注册(本文档后面将介绍)。
    Automatic registration of MessageCodesResolver (covered later in this document).

    #静态索引.html支持。
    Static index.html support.

    #自定义Favicon支持(本文档稍后将介绍)。
    Custom Favicon support (covered later in this document).

    #可配置WebBindingInitializerbean的自动使用(本文后面将介绍)。
    Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

#如果您想保留这些Spring-Boot MVC定制并进行更多MVC定制(拦截器、格式化程序、视图控制器和其他特性),您可以添加自己的WebMvcConfigurer类型的@Configuration类,但不添加@EnableWebMvc。
If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.

#如果要提供RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,并且仍然保留Spring Boot MVC自定义设置,可以声明WebMvcRegistrations类型的bean,并使用它来提供这些组件的自定义实例。
If you want to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, and still keep the Spring Boot MVC customizations, you can declare a bean of type WebMvcRegistrations and use it to provide custom instances of those components.

#如果您想完全控制springmvc,您可以添加自己的@Configuration,并用@EnableWebMvc注释,或者也可以添加自己的@Configuration annotated delegatingwebmvc配置,如@EnableWebMvc的Javadoc中所述。

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc, or alternatively add your own @Configuration-annotated DelegatingWebMvcConfiguration as described in the Javadoc of @EnableWebMvc.

1.ContentNegotiatingViewResolver 内容协商视图解析器

翻译:
Content:内容
Negotiating:谈判;协商
ViewResolver:视图分析器

在学习SpringMVC时,我们用到了ViewResolver(视图解析器):即根据方法的返回值取得视图对象(View),然后由视图对象决定如何渲染(转发,重定向)。

查看源码:找到WebMvcAutoConfiguration类,在其内部即可找到返回ContentNegotiatingViewResolver的viewResolver()方法

image

我们可以点进这类看看!找到对应的解析视图的代码:

image

点击getCandidateViews进去看,找到它是怎么获得候选的视图的:

image

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

我们再去研究下他的组合逻辑,看到有个属性viewResolvers,看看它是在哪里进行赋值的.

image

protected void initServletContext(ServletContext servletContext) {
        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);
                }
            }
			......

既然它是在容器中去找视图解析器,我们就可以给容器中添加一个视图解析器。ContentNegotiatingViewResolver可以帮我们组合。

1、在主程序中写一个视图解析器来试试:

image

package com.example.view;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;

import java.util.Locale;

@SpringBootApplication
public class ViewApplication {

    public static void main(String[] args) {
        SpringApplication.run(ViewApplication.class, args);
    }
    @Bean //放到bean中
    public ViewResolver myViewResolver(){
        return new MyViewResolver();
    }


    //我们写一个静态内部类,视图解析器就需要实现ViewResolver接口
    private static class MyViewResolver implements ViewResolver {
        @Override
        public View resolveViewName(String s, Locale locale) throws Exception {
            return null;
        }
    }
}

2、怎么看我们自己写的视图解析器有没有起作用呢?

application.properties文件中添加debug=true

image

启动项目,在Positive matches:中找到了自己定义的视图解析器!

image

如果想要使用自己定制化的东西,我们只需要给容器中添加这个组件,剩下的事情SpringBoot就会帮我们做了!

二、SpringBoot:转换器和格式化器

1.找到格式化转换器:

image

@Bean
public FormattingConversionService mvcConversionService() {
       Format format = this.mvcProperties.getFormat();
       WebConversionService conversionService = new WebConversionService((new DateTimeFormatters()).dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
        this.addFormatters(conversionService);
        return conversionService;
        }

点击getFormat()的源码,看到:

image

WebMvcProperties类中看到:

image

其中,class Format 源码:

image

WebMvcProperties类中,我们可以看到:properties for Spring MVC.

image

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

image

总结:

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.

  • 全面接管SpringMVC,官方文档如下:(不推荐)

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

全面接管即:SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己去配置!
只需在我们的配置类中要加一个@EnableWebMvc。访问如下:

image

  • 开发中,不推荐使用全面接管SpringMVC

思考问题?为什么加了一个注解,自动配置就失效了!
1.看EnableWebMvc的源码发现,它导入一个类这里发现它是导入了一个类:@Import({DelegatingWebMvcConfiguration.class})

image

2.DelegatingWebMvcConfiguration 继承 WebMvcConfigurationSupport

image

3.我们来回顾一下Webmvc自动配置类

image

三、SpringBoot:静态资源处理

SpringBoot最大的特点就是自动装配,开发步骤简单,程序员可以专注编写业务代码,不需要考虑以前那样一大堆的配置了。
在我们项目的中有许多的静态资源,比如css,js等文件,以前如果是一个web应用,我们的main下会有一个webapp,所有web资源在这里面的。在SpringBoot中又是如何应用的呢?

下面介绍一下,SpringBoot静态资源映射规则:

SpringBoot中,SpringMVC的web配置都在WebMvcAutoConfiguration这个配置类里面,可以去看看 WebMvcAutoConfigurationAdapter:

image

另外,可以看到addResourceHandlers()方法:添加资源处理

image

啥是 /webjars/** ,为啥都需要去 classpath:/META-INF/resources/webjars/ 找对应的资源?
Webjars本质就是以jar包的方式引入我们的静态资源 , 我们以前要导入一个静态资源文件,直接导入即可。
使用SpringBoot需要使用Webjars,网站地址

image

比如:
要使用jQuery,我们只要要引入jQuery对应版本的pom依赖即可!

image

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.6.0</version>
</dependency>

导入完毕,查看webjars目录结构,并访问Jquery.js文件

image

image

  • 项目中如何使用自己的静态资源?

我们去找staticPathPattern

/**
* Path pattern used for static resources.
*/
private String staticPathPattern = "/**";

发现第二种映射规则 :/** , 访问当前的项目任意资源,它会去找 resourceProperties 这个类:

image

再进入 Resources 类中,发现:

image

ResourceProperties 可以设置和我们静态资源有关的参数;这里面指向了它会去寻找资源的文件夹,以下四个目录存放的静态资源可以被我们识别:

"classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"
  • 自定义静态资源路径

我们也可以自己通过配置文件来指定一下,哪些文件夹是需要我们放静态资源文件的,在application.properties或者application.yaml中配置:

spring.web.resources.static-locations=classpath:/coding,classpath:zhou/

一旦自己定义了静态文件夹的路径,原来的自动配置就都会失效!

  • 首页的处理 WelcomePageHandlerMapping

image

点进去继续看:

image

image

欢迎页,静态资源文件夹下的所有 index.html 页面;被 /** 映射。

比如我访问: http://localhost:8083/ ,就会找静态资源文件夹下的 index.html

image

posted @ 2021-03-25 18:16  江河湖泊  阅读(36)  评论(0编辑  收藏  举报