SpringBoot-web开发(一): 静态资源的导入(源码分析)



在web开发中,最基本的一项就是导入静态资源,那么在springboot中怎么导入静态资源呢?答案就在源码中,接下来我们来分析分析~

首先在IDEA中连按两次shift键搜索WebMvcAutoConfugure类,这是的webMvc的自动配置类,关于springboot静态资源处理的方法就在其中
image-20200921192255315
我们往下滑,可以找到一个webMvc自动配置适配类WebMvcAutoConfigurationAdapter
image-20200921192234170
其中有个addResourceHandlers方法,这就是我们springboot项目添加处理静态资源的方法

我们接下来分析一下这段代码,我们会首先解析橙色部分代码,再解析蓝色部分代码,分别对应导入静态资源的两种方法!
image-20200921191250400


方式一:WebJars

addResourceHandlers方法中,上图标橙色的代码,里面提到了一个webjars的东西,这就是springboot导入静态资源的方式一,这是什么呢?

if (!registry.hasMappingForPattern("/webjars/**")) {
    
    
   customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
         .addResourceLocations("classpath:/META-INF/resources/webjars/")
         .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}

1. 什么是webjars?

参考博文:https://www.jianshu.com/p/ca568526f0bd
https://blog.coding.net/blog/spring-static-resource-process

通常对于web开发而言,我们常常需要导入一些静态资源,然而像jscssimages等静态资源版本管理是比较混乱的

  • 比如JqueryBootstrapVue.js等各个前端框架所依赖的各自组件的版本都不尽相同

  • 平时我们是将这些Web资源拷贝到Java的目录下,这种通过人工方式拷贝可能会产生版本误差,拷贝版本错误,前端页面就无法正确展示

所以,是否有一种像后端管理jar包一样的解决方案呢?这就引入了今天要介绍WebJars

扫描二维码关注公众号,回复: 11794654 查看本文章
  • WebJars是以Jar形式为Web项目提供资源文件,然后借助Maven这些依赖库的管理,保证这Web资源版本唯一性
  • Webjars多应用于基于Spring Boot创建微服务项目,需要打包所有资源为可执行的jar

2. webjars的使用

关于WebJars资源,官网:https://www.webjars.org/
image-20200921121150290
我们到该网站上找到自己所需资源,每个资源都有自己的maven坐标,在自己的工程中添加入maven依赖,即可直接使用这些资源了。
比如这里,导入jquery的maven依赖,同时可以在左边查看导入的jquery资源
image-20200921121830938

3. webjars结构

开始使用前,我们看下Jquerywebjars,了解下webjars包的目录结构

META-INF
    └─maven
        └─org.webjars
            └─jquery
                └─pom.properties
                └─pom.xml
    └─resources
        └─webjars
            └─jquery
                └─3.5.1
                       └─(静态文件及源码)

4. 解析源码

对以下代码进行分析:

//如果静态资源符合"/webjars/**"的格式
if (!registry.hasMappingForPattern("/webjars/**")) {
    
    
    //添加资源注册到"/webjars/**"
   customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
         .addResourceLocations("classpath:/META-INF/resources/webjars/")
         .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}

如果静态资源名符合/webjars/**,则到classpath:/META-INF/resources/webjars/路径下去寻找,添加资源注册到/webjars/**路径,这两个路径就是一个对应关系:

/webjars/**  --->  classpath:/META-INF/resources/webjars/

以后直接通过该注册路径的格式通过浏览器进行访问,就可以直接访问到静态资源;

而我们Webjars所有资源都符合这个路径结构,所以只需要通过maven的方式引入这个坐标,都是可以找到识别的,这就是我们导入静态资源的方式一
image-20200921122039544

5. 测试访问

接下来我们启动一下,测试能否访问到静态资源,源码中规定了访问格式/webjars/**就对应classpath:/META-INF/resources/webjars/**路径,这里是:

http://localhost:8080/webjars/jquery/3.5.1/jquery.js

就可以看到导入的juery的js静态文件
image-20200921123135697




方式二:staticPathPattern

addResourceHandlers方法中,上图标蓝色的代码,是springboot导入静态资源的第二个方式

1. 源码分析

//获取staticPathPattern
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
//如果静态资源路径符合staticPathPattern的格式
if (!registry.hasMappingForPattern(staticPathPattern)) {
    
    
    customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                                         .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                                         .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}

同样,首先获取了staticPathPattern,然后添加资源注册到该路径,那么这个路径是什么呢?

我们点入getStaticPathPattern
image-20200921194643300
再点入staticPathPattern
image-20200921194714793
发现了这个路径就是/**:也就是我们通过/**这个格式访问,都可以访问到静态资源,那么这个路径对应的真实路径是什么呢?

点击代码中的getStaticLocations(),可以看到四个路径
image-20200921230923841

"classpath:/META-INF/resources/":就是上述的webjars
"classpath:/resources/":reources目录下的resources目录,不存在自己新建
"classpath:/static/":resources目录下的static目录
"classpath:/public/":resources目录下的public目录,不存在自己新建

image-20200921200824407

2. 测试访问

比如我们在public目录下放一个静态文件1.js

hello

image-20200921203423657
然后我们启动主程序访问locaohost:8080/1.js,成功访问了静态资源
image-20200921203451706
总结localhost:8080下的所有请求的静态资源路径,都会去那四个目录找,就是四个存放静态资源的目录

我们可以进行测试,当有多个同名静态文件存在上述不同目录中时,优先级:resources>static>public




自定义资源路径

addResourceHandlers方法的最开始,有这样一个判断

//如果静态资源已经被自定义
if (!this.resourceProperties.isAddMappings()) {
    
    
    logger.debug("Default resource handling disabled");
    return;
}

可以在application.properties中自定义静态资源的路径,默认是/**

spring.mvc.static-path-pattern=/zsr/**

一般不建议这么做,设置了上述的方式二就失效了(除非显式定义为/**

猜你喜欢

转载自blog.csdn.net/qq_45173404/article/details/108721839
今日推荐