application.properties配置文件是springboot默认的加载文件,但是在现实研发过程中,默认的配置形式无法满足实际的需求,因此对有关配置的问题进行一次整理,主要包括:springboot默认扫描顺序、区分环境加载的两种方式、启动参数指定形式加载、自定义文件如何加载、配置如何拆分等。
一、application.properties配置文件存放位置及加载顺序
application.properties配置文件作为默认启动配置,在springboot项目中共有四个位置可以存放:
- 当前项目根目录config下:/config/
- 当前项目目录下:/
- resources目录config下:/resources/config/
- resources目录下:/resources/
其加载默认扫描优先级按照上边四种的排列顺序依次扫描
/config/
>/
>/resources/config/
>/resources/
当遇到重复的参数时,默认以第一次加载的为准
二、区分运行环境加载指定配置
- 最简单的一种就是application.properties中加入spring.profiles.active参数,然后新建不同环境下需要分别指定的文件,例如,以区分研发、测试、生产环境为例
| - application.properties
| - application-dev.properties
| - application-test.properties
| - application-prod.properties
application中加入
spring.profiles.active=dev
或者test、prod即可;不能同时设置
- 在启动参数中指定
java -jar
--spring.profiles.active=dev
XXX.jar
- Maven方式
该方式和之前的区别是:前两种打包后所有配置文件都会存在于jar包中,而mavne会针对性把用到的配置编译时加入到jar包中
- 在pom的project标签中加入如下配置
<project>
...
<profiles>
<profile>
<id>dev</id>
<properties>
<activatedProperties>dev</activatedProperties>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<activatedProperties>test</activatedProperties>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<activatedProperties>prod</activatedProperties>
</properties>
</profile>
</profiles>
...
</project>
# 注意
<activation>
<activeByDefault>true</activeByDefault>
</activation>
该属性用于指定要生效的环境,只能在一个中配置
- application.properties中配置
spring.profiles.active=@activatedProperties@
,其中**@activatedProperties@和pom中的test**对应,名称不能错。
三、加载项目外部配置文件
通过继承EnvironmentPostProcessor
接口在项目启动时加载指定的配置文件
- 项目代码目录新建包configuration,然后新建类
ExternalProperties
- 在 /resources/META-INF/ 下新建文件
spring.factories
,内容:
org.springframework.boot.env.EnvironmentPostProcessor=com.XXX.configuration.ExternalProperties
- ExternalProperties类
/**
* 主要实现 重写EnvironmentPostProcessor 接口postProcessEnvironment方法
* “PROGRAM-HOME-CONFIG”为自定义的启动参数,用来指定配置文件存储的绝对路径
* 本写法中的项目启动时会加载该文件夹下所有的配置文件,文件名称随便,请注意这一点,具体业务可自由开发
* 其中依赖的FileUtil类为一个工具类,都是基本的文件操作方法,可以自己写
* 如果不需要外部配置文件,可不配置,代码中会判断
* 下边的实现是基于配置添加高优先级策略,意思是外部配置不存在就用项目内的配置,外部配了会以外部为准
* 例如 MutablePropertySources 对象的addFirst方法,其他方法请查看源码解释
*/
public class ExternalProperties implements EnvironmentPostProcessor {
private Logger log = LoggerFactory.getLogger(getClass());
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
log.info("系统参数路径>>>"+System.getProperty("PROGRAM-HOME-CONFIG"));
// 获取指定目录下所有配置文件
String path = System.getProperty("PROGRAM-HOME-CONFIG");
// FileUtil.isNotExistDir判断路径是否存在
// 不存在结束加载
if(path==null || FileUtil.isNotExistDir(path)){
log.warn("{PROGRAM-HOME-CONFIG} is null");
return;
}
List<String> files = new ArrayList<String>();
getAllFileName(path,files);
if(files.size()>0){
for(String fileName : files){
File file = new File(path, fileName);
/**添加高优先级外部配置**/
if (file.exists()) {
MutablePropertySources propertySources = environment.getPropertySources();
log.info("Loading local settings from {}" , file.getAbsolutePath());
Properties properties = loadProperties(file);
propertySources.addFirst(new PropertiesPropertySource("Config", properties));
}
}
}
}
private Properties loadProperties(File f) {
FileSystemResource resource = new FileSystemResource(f);
try {
return PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Failed to load local settings from " + f.getAbsolutePath(), ex);
}
}
/**
* 获取某个文件夹下的所有文件
* @param fileNameList 存放文件名称的list
* @param path 文件夹的路径
* @return
*/
private List<String> getAllFileName(String path,List<String> fileNameList) {
File file = new File(path);
File[] tempList = file.listFiles();
for (int i = 0; i < tempList.length; i++) {
if (tempList[i].isFile()) {
String filename = tempList[i].getName();
if(filename ==null || filename.equals("") || filename.lastIndexOf(".")<=0){
continue;
}
String suffix = filename.substring(filename.lastIndexOf(".")+1).toLowerCase();
log.info("外部配置文件名称:" + filename);
if(suffix.equals("properties")){
log.info(filename+"已加入");
fileNameList.add(filename);
}else{
continue;
}
}
if (tempList[i].isDirectory()) {
log.info("外部配置子文件夹:" + tempList[i]);
getAllFileName(tempList[i].getAbsolutePath(),fileNameList);
}
}
return fileNameList;
}
}
四、自定义默认配置文件位置及名称
- 例如在resources目录下创建一个myconfig目录,目录中放入application.properties
这种情况需要在启动参数中使用
spring.config.location
参数来指定:
例如:java -jar XXX.jar--spring.config.location=classpath:/myconfig/
- 如果不想用默认的application作为名字,可以通过
spring.config.name
参数指定默认的配置文件名称
例如配置文件叫myapp.properties
在jar启动命令中加上该参数--spring.config.name=myapp
位置指定和名称指定可同时使用
五、配置文件拆分
spring.profiles.include
参数的使用
当我们想将db、redis等配置单独分离,避免单个配置文件过于臃肿时可考虑进行拆分,当然,也可以用第四部分中的方法灵活实现
(开发环境配置)
application-dev.properties
application-devDb.properties
application-devRedis.properties
在 application-dev.properties加入spring.profiles.include: devDb,devRedis
其他环境同理,spring.profiles.include 的作用是可以叠加激活新的profile