1、SpringMVC自动配置概览

image.pngimage.pngimage.png

2、功能简单分析

2.1、静态资源访问

(1)静态资源目录

类路径下:called /static (or /public or /resources or /META-INF/resources)
访问:当前项目路径/+静态资源名称
image.png
原理:静态映射/**
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源找不到404

(2)静态资源访问前缀

默认无前缀
但是我们可以通过配置来修改前缀

  1. spring.mvc.static-path-pattern=/res/**

(3)静态资源目录修改

可以指定到具体的自定义目录

  1. spring.web.resources.static-locations=classpath:/file/

(4)Webjars技术

引入jar中的静态资源,自定映射jar包内容
https://www.webjars.org/

  1. <dependency>
  2. <groupId>org.webjars</groupId>
  3. <artifactId>jquery</artifactId>
  4. <version>3.6.0</version>
  5. </dependency>

访问:本项目路径+/webjars/….
示例:http://localhost:8080/webjars/jquery/3.6.0/jquery.js
image.png

2.2、欢迎页

创建一个index.html存放在静态资源目录下,就可以访问到欢迎页,假如配置了访问前缀就只能按全路径进行访问,不然可以通过https://localhost:8080直接进行访问。

2.3、favicon.ico

favicon.icon直接存放在静态资源路径下就可以。
但是不能配置静态资源路径

3.4、静态资源配置原理

  • SpringBoot启动目录加载xxxAutoConfiguration类(自动配置类)
  • SpringMVC自动配置基本都在WebMvcAutoConfiguration配置类、生效

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnWebApplication(type = Type.SERVLET)
    @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
    @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
    @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
          ValidationAutoConfiguration.class })
    public class WebMvcAutoConfiguration {
    
  • 给容器中配了什么

    @Configuration(proxyBeanMethods = false)
      @Import(EnableWebMvcConfiguration.class)
      @EnableConfigurationProperties({ WebMvcProperties.class,
              org.springframework.boot.autoconfigure.web.ResourceProperties.class, WebProperties.class })
      @Order(0)
      public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
    
  • 配置文件的相关属性和xxx进行了绑定。WebMvcProperties==spring.mvc、ResourceProperties==spring.resources、WebProperties==spring.web

  • 只有一个有参构造器,所有参数都会从容器中找

    //ListableBeanFactory beanFactory 容器工厂
    //resourceHandlerRegistrationCustomizerProvider 资源处理器的自定义器
    //servletRegistrations 给应用注册Servlet、Filter
    public WebMvcAutoConfigurationAdapter(
                  org.springframework.boot.autoconfigure.web.ResourceProperties resourceProperties,
                  WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory,
                  ObjectProvider<HttpMessageConverters> messageConvertersProvider,
                  ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
                  ObjectProvider<DispatcherServletPath> dispatcherServletPath,
                  ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
    
  • 静态资源处理器

          @Override
          public void addResourceHandlers(ResourceHandlerRegistry registry) {
              if (!this.resourceProperties.isAddMappings()) {
                  logger.debug("Default resource handling disabled");
                  return;
              }
              addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
              addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                  registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                  if (this.servletContext != null) {
                      ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
                      registration.addResourceLocations(resource);
                  }
              });
          }
    
  • 可以通过addMapping配置禁用掉所有资源访问

    spring.web.resources.add-mappings=false
    
  • 配置了默认的静态资源路径

      public static class Resources {
    
          private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
                  "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
    
          /**
           * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
           * /resources/, /static/, /public/].
           */
          private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
    
  • 欢迎页处理器源码规则

          @Bean
          public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
                  FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
              WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
                      new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
                      this.mvcProperties.getStaticPathPattern());
              welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
              welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
              return welcomePageHandlerMapping;
          }
    
      WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
              ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
          if (welcomePage != null && "/**".equals(staticPathPattern)) {
              logger.info("Adding welcome page: " + welcomePage);
              setRootViewName("forward:index.html");
          }
          else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
              logger.info("Adding welcome page template: index");
              setRootViewName("index");
          }
      }