四、Web场景之静态资源配置原理

本文深入探讨了SpringBoot在Web场景下的静态资源配置原理,从WebMvcAutoConfiguration类开始,分析了如何通过配置文件绑定属性,并详细解释了资源处理的默认规则,包括静态资源路径和缓存策略。此外,还介绍了欢迎页的处理规则,涉及到HandlerMapping的概念。通过源码解析,揭示了SpringMVC中静态资源和欢迎页的管理机制。
摘要由CSDN通过智能技术生成

四、Web场景之静态资源配置原理

  前边我们讲过,研究SpringBoot原理的第一步,首先启动SpringBoot,它会帮我们默认加载许多的自动配置类,就是那一堆 xxxAutoConfiguration ,我们想要研究Web场景下的静态资源配置,所以我们直接来到 spring-boot-autoconfigure-2.4.0.jar 包下的web场景 ,里边有一个 WebMvcAutoConfiguration ,大部分SpringMVC功能的自动配置都在这里边,接下来我们就从这里开始研究。

  现在,我们拿到了这个类,先不要急着去看内容,首要应该看这个类是否生效,从类上边的这些注解来看,它是生效的
在这里插入图片描述

  既然是生效的,我们就来看下它给容器中配了什么,因为配了什么,就会有什么样的功能。

  来到 WebMvcAutoConfiguration 类往下看,翻着翻着看到下边又有一个类

在这里插入图片描述

  我们要注意一下这个类,因为这个类上边有一个注解 @EnableConfigurationProperties ,表示配置文件和相关属性进行了绑定,点进去看看是怎么绑定的

在这里插入图片描述
在这里插入图片描述
  得出的结果是:WebMvcProperties == spring.mvc、ResourceProperties == spring.resources

  得出这个结论后,我们继续看,咦,发现 WebMvcAutoConfigurationAdapter 这个配置类只有一个有参构造器,我们知道,如果一个配置类只有一个有参构造器,那么这个有参构造器所有参数的值都会从容器中确定 ,所以我们来看下这个构造器的参数,看看它到底获取了哪些东西:

1. 配置类只有一个有参构造器:容器获取参数值

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;
		}

  我们来分析它的参数及代表的含义:

  ResourceProperties :获取和spring.resources绑定的所有的值的对象

  WebMvcProperties :获取和spring.mvc绑定的所有的值的对象

  ListableBeanFactory :Spring的bean工厂

  ObjectProvider :找到所有的HttpMessageConverters

  ObjectProvider :找到资源处理器的自定义器

  ObjectProvider:DispatcherServlet路径

  ObjectProvider<ServletRegistrationBean<?>>:给应用注册Servlet、Filter等等

  现在,我们的配置类已经拿到了它想要的所有东西,接下来来看他要干嘛,在这里我们先不去关注其他的一些功能,主要关注资源处理有关的东西,比如我们一直向下找,有一个如下的类

2. 资源处理的默认规则

public void addResourceHandlers(ResourceHandlerRegistry registry) {
			//首先拿到了spring.resources下的一个属性addMappings,配置为false就直接返回,下边的代码无效了
			//这里表示,我们可以通过配置文件,禁用掉静态资源的路径映射,静态资源就不能访问了
			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));
			}
            
            //静态资源路径的配置规则,staticPathPattern 在spring.mvc里边
            //如果我们配置了,就获取我们配置的值,否则为“/**”,也就是在我们指定的位置去找
            //指定默认位置在哪里呢,下边的代码有个resourceProperties.getStaticLocations()
            //默认路径的代码贴到这段下边,而且静态资源都有缓存策略
			String staticPathPattern = this.mvcProperties.getStaticPathPattern();
			if (!registry.hasMappingForPattern(staticPathPattern)) {
				customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
						.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
						.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
			}
		}

  默认静态资源路径源码

//下边为四个默认路径
public class ResourceProperties {
    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;
    //下边代码省略没有贴

  上边就是资源处理的默认规则的主要代码啦,debug的结果已经在注释写明白了,感兴趣的可以自己debug一下哦!

3. 欢迎页的处理规则

  我们继续往下找,发现一个 EnableWebMvcConfiguration 类,里边有一个 welcomePageHandlerMapping() 方法,是用来处理欢迎页的处理规则的,在看这段代码之前,我们先来普及一个知识点, 在SpringMVC中,有一个 HandlerMapping,叫做处理器映射,作用是保存了每一个Handler能处理哪些请求 ,知道了这个以后,我们就可以理解 welcomePageHandlerMapping() 这个方法了,表示谁能处理这个欢迎页的映射规则。我们来看代码

		@Bean
		//参数已经从容器中获取好了,我们不用考虑
		public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
				FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
			//new 并初始化一个WelcomePageHandlerMapping,里边代码在下边展示
			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");
		}
	}

  上边就是欢迎页的处理规则主要代码啦,debug的结果已经在注释写明白了,感兴趣的可以自己debug一下哦!

  Web场景的静态资源配置原理到这里就分析结束了,下篇再见吧!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anton丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值