文件系统是我们开发过程中常常会接触的问题。那么在Spring Boot框架中,文件的访问又是什么样的呢?今天在此做一个总结。
1,file和classpath
存放在电脑上实际位置的文件,在Spring Boot中用file:开头表示。例如:
file:a.txt当前目录下的a.txt文件。当前路径在开发环境下一般为Maven项目的目录下(与pom.xml同目录下),在打包为jar文件后当前路径即为运行jar文件时的运行路径。file:D:\a.txt表示绝对路径,在此不多赘述。
而在jar文件内部中,我们一般把文件路径称为classpath,所以读取内部的文件就是从classpath内读取,classpath指定的文件不能解析成File对象,但是可以解析成InputStream。例如:
classpath:/a.txtjar包根目录下的a.txt。classpath以/开头表示绝对路径,即为jar包根目录。
2,Spring Boot的静态资源访问
我们都知道Spring Boot工程文件夹中的src/main/resources是用于存放资源的地方。默认时Spring Boot打包之后静态资源位置如下:
classpath:/staticclasspath:/publicclasspath:/resourcesclasspath:/META-INF/resources
在Spring Boot中classpath的根目录就对应工程文件夹下的src/main/resources。
可以先看这个例子:
在工程文件夹下src/main/resources/static下放入图片qiqi.png:
运行,访问127.0.0.1:8080/qiqi.png,效果如下:
这个例子可见外部访问的资源路径和Spring工程中资源文件路径的一一对应关系。即外部访问时的“根目录”即对应着上述的四个静态资源位置(classpath)。
还可以新建Controller类,写如下方法:
@GetMapping("/pic")
public String ShowPic() {
return "/qiqi.png";
}
复制代码
运行,访问127.0.0.1:8080/pic,效果同上。
在这个Controller方法中,上面GetMapping是路由路径,return的是对应的资源路径。
其实这个默认的资源路径是可以修改的。
我们需要知道在配置文件application.properties中可以加入下列两个配置项:
spring.web.resources.static-locations
spring.mvc.static-path-pattern
复制代码
其中spring.mvc.static-path-pattern代表的是应该以什么样的路径来访问静态资源,也就是只有静态资源满足什么样的匹配条件,Spring Boot才会处理静态资源请求。根据上述例子我们知道了这个配置默认值为/**。假设在上述工程配置文件中加入:
spring.mvc.static-path-pattern=/resources/**
复制代码
那么再访问我们那个图片就要访问网址:127.0.0.1:8080/resources/qiqi.png
再者,spring.web.resources.static-locations用于指定静态资源文件的查找路径,查找文件是会依赖于配置的先后顺序依次进行。根据上述例子可见这个值默认是:
classpath:/static,classpath:/public,classpath:/resources,classpath:/META-INF/resources
复制代码
其实上面提到了Spring Boot默认资源文件位置,实质上就是这个配置的值。
假设在上述工程中配置文件写入:
spring.web.resources.static-locations=classpath:/myRes
复制代码
那么我们要将qiqi.png放在项目文件夹的src\main\resources\myRes文件夹中,才能访问:
配置此项后,默认值将失效!
还可以使用磁盘路径例如:
spring.web.resources.static-locations=file:res
复制代码
即指定资源文件在项目文件夹中的res中(即打包后运行jar文件时的运行路径下的res文件夹中)。也可以使用绝对路径。
通俗地讲,spring.mvc.static-path-pattern配置指定了我们外部访问的“根目录”,spring.web.resources.static-locations配置了对应的资源位置。
3,Spring Boot的配置文件位置指定
我们也知道Spring Boot的配置文件默认是位于classpath:/application.properties,默认会被打包进jar文件。
其实我们也可以修改这个配置文件的位置。
在我们的Spring主类上加入如下注解:
@PropertySource(value={"自定义配置文件路径"})
复制代码
value表示配置文件位置,也可以填多个:
@PropertySource(value={"配置1路径", "配置2路径"})
复制代码
此处以我的主类全部代码为例:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;
@SpringBootApplication
@PropertySource(value={"file:self.properties"})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
复制代码
即定义配置文件为项目文件夹下的self.properties文件(打包后运行jar文件时的运行目录下的self.properties文件)。
4,多环境的配置文件外置方案
我们知道,默认情况下,我们可以在src/main/resources文件夹下创建多个配置文件以对应多个不同环境下的配置,方便灵活切换,例如开发-生产环境下,我们一共有三个配置文件:
application.properties
application-dev.properties
application-prod.properties
复制代码
然后在主配置文件application.properties里面配置一个配置项,即可一键切换配置环境:
# 指定当前使用开发环境配置文件
spring.profiles.active=dev
复制代码
我们默认的配置文件名是application,因此多环境的情况下,配置文件命名如下:
application-环境配置名.properties
复制代码
主配置文件就是application.properties,在里面配置:
spring.profiles.active=环境配置名
复制代码
运行时即可使用指定环境的配置文件。
这个时候想配置文件外置,如果按照上述第3部分的方法来,发现就不行了。那么多环境配置的情况下,配置文件如何外置呢?
我们需要先知道,其实Spring Boot会默认在这四个位置扫描配置文件:
file:./config/
file:./
classpath:/config/
classpath:/
复制代码
我们可以指定spring.config.location属性,来实现自定义Spring Boot的配置文件扫描路径。spring.config.location属性不仅可以设定扫描指定的配置文件,还可以指定扫描指定文件夹。
在我们的main方法中最开头,使用System.setProperty方法即可设定,下面给几个例子:
// 扫描项目文件夹(jar运行目录)中Resources/config目录中所有的配置文件
System.setProperty("spring.config.location", "file:Resources/config/");
// 扫描项目文件夹(jar运行目录)中Resources/config/app.properties文件
System.setProperty("spring.config.location", "file:Resources/config/app.properties");
// 扫描项目文件夹(jar运行目录)中Resources/config目录和Resources/config2目录中所有的配置文件
System.setProperty("spring.config.location", "file:Resources/config/, file:Resources/config2/");
复制代码
可见spring.config.location属性比较灵活,既可以设定文件还可以指定文件夹,注意指定的如果是文件夹,路径最后一定要以/结尾。指定多个文件或者文件夹时路径中间以英文逗号分隔。
好了,知道了spring.config.location属性,我们就知道多环境配置文件外置的方法了。例如我想把所有配置文件application.properties、application-dev.properties和application-prod.properties放到项目文件夹下的Resources/config目录下,那么我的完整主类代码如下:
package com.gitee.swsk33.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
// 设定配置文件扫描目录
System.setProperty("spring.config.location", "file:Resources/config/");
SpringApplication.run(TestApplication.class, args);
}
}
复制代码
可见很简单,只在主方法main中最头部写了System.setProperty("spring.config.location", "file:Resources/config/");这一行代码即可完成配置。
然后我的三个配置文件放在项目文件夹下的Resources/config目录下:
再在主配置文件里面配置:
spring.profiles.active=dev
复制代码
运行,即可使用开发环境的配置文件application-dev.properties了。
5,配置文件改名
我们也知道,Spring Boot配置文件默认名字是application.properties,Spring Boot默认情况下也是通过搜寻这个名字的文件找到配置文件的。
如果说想改配置文件的名字怎么做呢?其实除了上述直接指定配置文件路径以外,还可以修改属性spring.config.name来实现,也是使用System.setProperty方法来修改。例如在main方法最前面写上:
System.setProperty("spring.config.name", "config");
复制代码
那么Spring Boot就会去搜寻名为config.properties的文件作为配置文件。
因此可见spring.config.name的默认值为application,这个值不需要写扩展名,扩展名会在Spring Boot中自动适配。
上面修改了spring.config.name属性为config,那么如果说是多环境配置,我们的其余环境的配置文件也要跟着改为如下:
config-dev.properties
config-prod.properties
复制代码
6,总结
Spring Boot的资源文件访问和我们普通Java程序可能有所不同,大家一定要注意资源文件配置,以及配置文件的加载。
关于配置文件外置,本文参考官方文档:




近期评论