1.springboot处理静态资源
 1.STS:new-spring starter-设置(选择需要的场景,web)
 2.springboot是一个jar,因此 静态资源就不是再存放在webapp中,存放在哪里呢?
   a.静态资源的存放路径通过WebMvcAutoConfiguration类中addResourceHandlers指定(/webjars/**)
     1.https://www.webjars.org/
        传统的项目引入js等静态资源是将这些资源下载并手工放入webapp目录中,而Springboot将静态资源存入到jar包中;
     2.使用:
       springboot将这些静态资源直接以jar文件(maven)的方式引入项目;
        引入使用的时候从jar的目录结构webjars开始写(http://localhost:8080/webjars/jquery/3.3.1-2/jquery.js)        
         <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1-2</version>
        </dependency>
    b.如何写静态资源,如何将静态资源放入springboot之中?
      1.将自己写的静态资源变为jar,引入项目;(不推荐;需要打包成符合springboot目录结构的jar);
      2.springboot自动扫描的方式(推荐):
        a.springboot的约定:
           1.springboot将一些目录结构设置成静态资源存放目录,我们只需要将静态资源放入到这些目录即可(webapp);
           2.springboott约定的静态资源目录(src/main/resources):(在springboot 里,WebMvcAutoConfiguration类的        addResourceHandlers()中resourceProperties.getStaticLocations()查看)
             在ResourceProperties类中CLASSPATH_RESOURCE_LOCATIONS中定义了;
             private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
            "classpath:/META-INF/resources/", "classpath:/resources/",
            "classpath:/static/", "classpath:/public/" };
           3.在以上资源目录放入资源文件后,在访问时不需要写前缀,直接访问即可http://localhost:8080/index.html;
           4.传统的web项目可以在web.xml中配置欢迎页,springboot在WebMvcAutoConfiguration类中提供了welcomePageHandlerMapping()来设置欢迎页
             该方法中的getWelcomePage()中location + "index.html"来设置欢迎页(即任意静态资源目录下的index.html页面就是欢迎页);
         4.在网站中,网页标签的logo是固定名字的:favicon.ico
            a.自定义favicon.ico
              1.在springboot中:在WebMvcAutoConfiguration类中的faviconHandlerMapping()方法中定义了favicon.ico;
              2.faviconRequestHandler():该方法中的resolveFaviconLocations()方法设置了一个路径(getStaticLocations()),通过源码可以发现
              这个路径是在ResourceProperties类中CLASSPATH_RESOURCE_LOCATIONS中定义的路径(即需要为网站添加ico图标只需要将favicon.ico文件放入到任意一个资源文件目录中);
              
    总结:
     1.需要知道springboot资源文件的约定(可以通过源码);
     2.使用静态资源:只需要将静态资源放入springboot约定的资源文件目录中;
     3.其他特定的文件(欢迎页,ico),只需要将(index.html,favicon.ico)其放入springboot约定好的资源目录中;
3.如何自定义静态资源目录?
 1.通过WebMvcAutoConfiguration类中addResourceHandlers()中的resourceProperties.getStaticLocations()属性可以得到默认的资源配置目录;
 2.如果不想用默认的资源配置文件目录,可通过中的resourceProperties中的prefix+属性名在全局配置文件中配置;
   spring.resources.static-locations=classpath:/views/,classpath:/res/
 3.自定义静态资源目录后默认的就失效了;

addResourceHandlers():

public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
                CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
                if (!registry.hasMappingForPattern("/webjars/**")) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }

                String staticPathPattern = this.mvcProperties.getStaticPathPattern();
                if (!registry.hasMappingForPattern(staticPathPattern)) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }

            }
        }

 getStaticLocations();

public class ResourceProperties {
    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
   

    public String[] getStaticLocations() {
        return this.staticLocations;
    }
.......
}

欢迎页

@Bean
        public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
            return new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
        }
private Optional<Resource> getWelcomePage() {
            String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
            return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
        }

 ico

@Bean
            public ResourceHttpRequestHandler faviconRequestHandler() {
                ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
                requestHandler.setLocations(this.resolveFaviconLocations());
                return requestHandler;
            }
@Bean
            public ResourceHttpRequestHandler faviconRequestHandler() {
                ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
                requestHandler.setLocations(this.resolveFaviconLocations());
                return requestHandler;
            }

 private List<Resource> resolveFaviconLocations() {
                String[] staticLocations = WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter.getResourceLocations(this.resourceProperties.getStaticLocations());
                List<Resource> locations = new ArrayList(staticLocations.length + 1);
                Stream var10000 = Arrays.stream(staticLocations);
                ResourceLoader var10001 = this.resourceLoader;
                this.resourceLoader.getClass();
                var10000.map(var10001::getResource).forEach(locations::add);
                locations.add(new ClassPathResource("/"));
                return Collections.unmodifiableList(locations);
            }