栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot 静态资源源码分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot 静态资源源码分析

层层递进的关系来分析SpringBoot的部分源码

1. SpringBoot 静态资源源码分析

2. SpringBoot 请求处理源码分析

3. SpringBoot 响应处理源码分析

4. SpringBoot 视图解析器源码分析

一、 静态资源访问 1. 静态资源目录
只要放在类路径下:called /static(or /public or /resources or /meta-INF/resources)
访问当前项目路径/ + 静态资源名,只需要写静态资源名就能访问,springboot

原理:/**
收到请求后先去匹配 controller,如果不能处理就去交给静态资源处理器。

改变默认的静态资源位置

  web:
    resources:
      static-locations: classpath:/path
2. 静态资源访问前缀
spring:
  mvc:
    static-path-pattern: /res/**

当前项目 + static-path-pattern + 静态资源名 = 静态资源文件夹下的

二、欢迎页支持 1. 自动加载的欢迎页面
  1. 在静态资料路径下 index.html
    1. 可以配置静态资源路径
    2. 但是不可以配置静态资源的访问前缀。否则导致index.html 不能被默认访问
  2. controller 能够处理 /index 请求的controller 自动会请求
2. favicon支持

将 favicon.ico 放置在静态资源路径下,会自动将favicon.ico 作为页面小图标

三、静态资源配置原理 1. 加载配置类源码
  1. springboot启动默认加载 XXXAutoConfiguration类(自动配置类)
  2. SpringMVC功能的自动配置类是 WebMvcAutoConfiguration
@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {}
2. 配置类生效源码
@Configuration(
        proxyBeanMethods = false
    )
    @import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
    @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})
    @Order(0)
    public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {}

配置文件的相关属性和什么进行了绑定

如果配置中只有一个有参构造器,那么属性会自动从容器中找

// ResourceProperties 获取 spring.resources
// WebMvcProperties 获取 sprint.mvc
// ListableBeanFactory 获取bean 工厂
// ResourceHandlerRegistrationCustomizer 获取资源处理自定义器
// ...
        public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider messageConvertersProvider, ObjectProvider resourceHandlerRegistrationCustomizerProvider, ObjectProvider dispatcherServletPath, ObjectProvider> servletRegistrations) {
            this.resourceProperties = (Resources)(resourceProperties.hasBeenCustomized() ? resourceProperties : webProperties.getResources());
            this.mvcProperties = mvcProperties;
            this.beanFactory = beanFactory;
            this.messageConvertersProvider = messageConvertersProvider;
            this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
            this.dispatcherServletPath = dispatcherServletPath;
            this.servletRegistrations = servletRegistrations;
            this.mvcProperties.checkConfiguration();
        }
3. 资源处理的默认规则源码

这样可以看出默认规则下的SpringBoot 以什么路径作为静态资源,以及为webjar的配置

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(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }

            }
        }
4. 可以直接禁用所有静态资源
spring:
  web:
    resources:
      add-mappings: false
5. 默认资源配置源码
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = 
new String[]{"classpath:/meta-INF/resources/", 
"classpath:/resources/", "classpath:/static/", 
"classpath:/public/"};
    private String[] staticLocations;
    private boolean addMappings;
    private final ResourceProperties.Chain chain;
    private final ResourceProperties.Cache cache;
6. 欢迎页源码分析

我们都知道SpringBoot中有默认的欢迎页面,这里是用SpringBoot给我们提供的类 WelcomePageHandlerMapping 来进行提供的,在访问这个HanderMapping之前,其实SpringBoot 会先去访问 RequestMappingHandlerMapping,即程序员自己创建的 controller 的HandlerMapping,这也说明了我们编写的Controller的优先级是最高的(后面有详细描述)。

@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
    WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
    welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
    welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
    return welcomePageHandlerMapping;
}

WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
    if (welcomePage != null && "/**".equals(staticPathPattern)) {
        logger.info("Adding welcome page: " + welcomePage);
        this.setRootViewName("forward:index.html");
    } 
    else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
        logger.info("Adding welcome page template: index");
        this.setRootViewName("index");
    }

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/601196.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号