美文网首页
springboot 静态资源访问原理

springboot 静态资源访问原理

作者: Exception_Cui | 来源:发表于2021-09-02 18:21 被阅读0次

    SpringBoot 静态资源原理

    SpringBoot启动默认加载  xxxAutoConfiguration 类(自动配置类)    
    SpringMVC功能的自动配置类 WebMvcAutoConfiguration
    所以我们就可以分析WebMvcAutoConfiguration 这个类
    
    WebMvcAutoConfiguration.java
    @Configuration(         //此类不被代理
        proxyBeanMethods = false 
    )
    @ConditionalOnWebApplication(   //是不是一个web的应用, web应用就包含SERVLET
        type = Type.SERVLET
    )
    
    //是不是包含 Servlet  DispatcherServlet WebMvcConfigurer  web应用本身就包含
    @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
    
    //不包含  WebMvcConfigurationSupport 这个类
    @ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
    @AutoConfigureOrder(-2147483638)
    @AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
    public class WebMvcAutoConfiguration {
        ...
        public WebMvcAutoConfiguration() {
        } 
        
    
    内部类 WebMvcAutoConfiguration ->WebMvcAutoConfigurationAdapter
    
        
        @Configuration(
            proxyBeanMethods = false
        )
        @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
        
        //关键
        //EnableConfigurationProperties  开启绑定和 将绑定的类添加到容器
        //WebMvcProperties == "spring.mvc"
        //ResourceProperties =="spring.resources"
        //WebProperties =="spring.web"
        //此处就说明了 我们 配置文件 为什么可以生效
        @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class}) 
        
        
        
        @Order(0)
        public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
            
              
        //springboot 底层的代码 如果类只有一个构造器
        //那么 所有的构造器使用的类 都是在spring 的IOC容器里面获取的
        
        public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> 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();
                }
                
        }
        
        
        
        
        
        @Bean
        @ConditionalOnMissingBean  //配置视图解析器,此处不是重点,如果我们配置了,就不用springboot的
        public InternalResourceViewResolver defaultViewResolver() {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
                resolver.setPrefix(this.mvcProperties.getView().getPrefix());
                resolver.setSuffix(this.mvcProperties.getView().getSuffix());
                return resolver;
        }
    
    
        //静态资源加载原理
            //重点
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
                // resourceProperties.isAddMappings  是不是默认禁用springboot 进行静态资源资源管理
                
                /*
                spring:
                  web:
                    resources:
                      add-mappings:true 
                                         默认值是true, 就是不禁用
                */
                
                if (!this.resourceProperties.isAddMappings()) {
                    logger.debug("Default resource handling disabled");
                } else {
                    // 如果我们使用了webjars  这里就是说明 为什么 webjars 的静态资源可以访问
                    // 会在每个webjars jar包里面寻找/META-INF/resources/webjars/  路径下的文件
                    //将他们 添加到spring boot 的静态资源
                    this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/"); 
                    
                    
                    /*
                    spring:
                        mvc:
                            static-path-pattern: /res/**
                            如果我们配置前缀, 所以资源路径就会编程 "/res/**"    
                    */
                    // this.mvcProperties.getStaticPathPattern() = "/**"    默认的静态资源路径规则
                    this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                        /*    
                        spring:
                            web:
                                resources:
                                        static-locations: classpath:/haha/
                                  如果我们配置了 静态资源路径,就会在我们配置的静态资源路径下面寻找
                                  this.resourceProperties.getStaticLocations() 就成了 /haha/
                        */
                        // this.resourceProperties.getStaticLocations()  = {"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
                        //默认值,这里就说明了为什么springBoot的静态资源需要放到这几个文件夹下面
                        registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                        
                        //如果使用原生的servlet,也将资源添加到原生的context下面
                        if (this.servletContext != null) {
                            ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
                            registration.addResourceLocations(new Resource[]{resource});
                        }
    
                    });
                }
        }
    
    
    欢迎页处理规则 WebMvcAutoConfiguration.java
    //HandlerMapping:处理器映射器。保存了每一个Handler能处理哪些请求。  
     @Bean
    public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
         WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, 
        //将/index.html 传入    //将前缀也传入
        this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
        welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
        welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
        return welcomePageHandlerMapping;
    }
    
    WelcomePageHandlerMapping.java
    WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
        //检测 welcomePage  /index.html 是不是存在 
        //检测 前缀是否匹配    
        // 这里就说明了,如果我们使用了静态资源使用的前缀,就无法匹配的默认的欢迎页
        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");
        }
    }
    
    网站图标配置
    这里是浏览器的功能,浏览器会自动请求访问/favicon.ico这个资源,如果存在浏览器就加上,和springboot 无关
    

    相关文章

      网友评论

          本文标题:springboot 静态资源访问原理

          本文链接:https://www.haomeiwen.com/subject/tsscwltx.html