• SpringBoot2 静态资源配置原理


    • 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, ResourceProperties.class })
        @Order(0)
        public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}
    • 配置文件的相关属性和xxx进行了绑定。WebMvcProperties==spring.mvc、ResourceProperties==spring.resources

    1、配置类只有一个有参构造器

        //有参构造器所有参数的值都会从容器中确定
    //ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象
    //WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
    //ListableBeanFactory beanFactory Spring的beanFactory
    //HttpMessageConverters 找到所有的HttpMessageConverters
    //ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。=========
    //DispatcherServletPath  
    //ServletRegistrationBean   给应用注册Servlet、Filter....
        public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,
                    ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
                    ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
                    ObjectProvider<DispatcherServletPath> dispatcherServletPath,
                    ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
                this.resourceProperties = resourceProperties;
                this.mvcProperties = mvcProperties;
                this.beanFactory = beanFactory;
                this.messageConvertersProvider = messageConvertersProvider;
                this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
                this.dispatcherServletPath = dispatcherServletPath;
                this.servletRegistrations = servletRegistrations;
            }

    2、资源处理的默认规则

    @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry) {
                if (!this.resourceProperties.isAddMappings()) {
                    logger.debug("Default resource handling disabled");
                    return;
                }
                Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
                CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
                //webjars的规则
                if (!registry.hasMappingForPattern("/webjars/**")) {
                    customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
                            .addResourceLocations("classpath:/META-INF/resources/webjars/")
                            .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }
                
                //
                String staticPathPattern = this.mvcProperties.getStaticPathPattern();
                if (!registry.hasMappingForPattern(staticPathPattern)) {
                    customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                            .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                            .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }
            }

    所以可以禁用所有静态资源规则:

    YML如下:

    spring:
      resources:
        add-mappings: false   禁用所有静态资源规则
    @ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
    public class ResourceProperties {
    
        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;

    欢迎页的处理规则:

      //  HandlerMapping:处理器映射。保存了每一个Handler能处理哪些请求。    
    
        @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, Optional<Resource> welcomePage, String staticPathPattern) {
            if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {
                //要用欢迎页功能,必须是/**
                logger.info("Adding welcome page: " + welcomePage.get());
                setRootViewName("forward:index.html");
            }
            else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
                // 调用Controller  /index
                logger.info("Adding welcome page template: index");
                setRootViewName("index");
            }
        }

    本文来自博客园,作者:咸瑜,转载请注明原文链接:https://www.cnblogs.com/bi-hu/p/15230494.html

  • 相关阅读:
    《一起学Windows phone7开发》系列视频课程
    Windows Phone 7 开发 31 日谈——第19日:推送通知
    周金根 2010年blog汇总:企业架构、敏捷个人、模型驱动
    Windows Phone 7 开发 31 日谈——第4日:设备方向
    Windows Phone 7 开发 31 日谈——第3日:返回键
    JavaScript初学者应注意的七个细节
    [项目过程中所遇到的各种问题记录]图表篇——有关MSChart的一些小技巧
    Windows Phone 7 开发 31 日谈——第2日:页面间导航
    Windows Phone 7 开发 31 日谈——第22日:应用?还是 游戏?
    Windows Phone 7 开发 31 日谈——第11日:加速感应器
  • 原文地址:https://www.cnblogs.com/bi-hu/p/15230494.html
Copyright © 2020-2023  润新知