SpringBoot静态资源配置原理(源码分析)

静态资源的默认配置也是在自动配置类中,我们知道SpringBoot启动会默认加载xxxAutoConfiguration自动配置类,而关于静态资源配置的在WebMvcAutoConfiguration类中。打开源码查看:

我们需要重点关注该类中的内部类EnableWebMvcConfiguration的相关配置

还有另外一个WebMvcAutoConfigurationAdapter类,该类是一个配置类,只有一个有参构造器:

        public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
            this.resourceProperties = resourceProperties;
            this.mvcProperties = mvcProperties;
            this.beanFactory = beanFactory;
            this.messageConvertersProvider = messageConvertersProvider;
            this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
            this.dispatcherServletPath = dispatcherServletPath;
            this.servletRegistrations = servletRegistrations;
        }

在这个构造器中所有参数的值都会从容器中确定,如resourceProperties获取的是同spring.resources绑定的所有的值的对象,mvcProperties获取的是同spring.mvc绑定的所有值的对象等等。

然后我们看该类的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(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }

            }
        }

如果我们在application.yaml中设置了spring.resources.add-mappings:false,那么会禁用掉所有的静态资源规则。

为什么呢,这句代码很好的解释了这一切:

而关于我们配置静态资源规则的属性如spring.resources.static-locations也在代码中体现了

而关于配置的关键属性值是从ResourceProperties配置类中获取的,ResourceProperties配置类中的属性又和application.yaml配置文件中的信息绑定在一起。

这也解释了为什么默认的静态资源路径是那四个,而我们修改配置文件中spring.resources.static-locations的值来修改ResourceProperties配置类中的staticLocations属性的值,从而绑定在一起,使得自定义化配置会生效。

接下来看看对欢迎页的处理,找到EnableWebMvcConfiguration类中的welcomePageHandlerMapping方法,查看代码如下:

        @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的处理器映射器中,打开该类的源码查看,看该类的构造器源码:

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

    }

发现如果存在欢迎页,则跳转到index.html页面去了。这也解释了为什么只有当静态资源前缀没有的情况(默认spring.mvc.static-path-pattern的值是"/**",如果设置了后就不是了,则下面红框内的表达式为false,无法得到执行,不会跳转到index.html页面)下才会跳转欢迎页,如果是在配置文件application.yaml中设置了spring.mvc.static-path-pattern属性的值,那么久欢迎页无效。

总结关于SpringBoot静态资源配置的原理,静态资源的配置是在WebMvcAutoConfiguration自动配置类中进行的,在该类中又有一个WebMvcAutoConfigurationAdapter静态内部类,这个静态内部类的构造器方法从容器中获取了所有关于静态资源配置的配置类如ResourceProperties等,在一个名为addResourceHandlers方法中规定了静态资源配置的规则,而ResourceProperties配置类与application.yaml配置文件中的属性相关联,来达到修改静态资源配置的目的。而关于欢迎页的处理在EnableWebMvcConfiguration内部类的welcomePageHandlerMapping()方法中,该方法实例化了WelcomePageHandlerMapping对象,在WelcomePageHandlerMapping类中定义了对欢迎页跳转到index.html的规定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值