写点什么

SpringBoot- 技术专题 -war 包部署读取外部配置 Properties

发布于: 2020 年 11 月 02 日
SpringBoot-技术专题-war包部署读取外部配置Properties

1. 读取文件扩展接口:

org.springframework.boot.env.EnvironmentPostProcessor

我的项目使用场景起因是: 在同一台机器上起了两个tomcat实例, 每个项目的日志文件打印路径要配成不同, 如果每次打包手动修改打印日志的路径太费时费力, 所以考虑把配置文件每个tomcat放一份, 启动时自动读取当前tomcat文件下的配置就好.

2. 自定义配置文件存放路径

tomcat的conf文件夹下面

3. myspringboot.properties配置文件

logging.path=/data/logs

4. 实现EnvironmentPostProcessor接口

package com.hlz.web.common.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import javax.servlet.ServletContextEvent;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment,
SpringApplication application) {
//tomcat路径
String property = System.getProperty("catalina.home");
System.out.println("catalinahome:"+property);
String path =property+File.separator+"conf"+File.separator+"myspringboot.properties";
File file = new File(path);
System.out.println("Loading local settings from : "+path);
if (file.exists()) {
MutablePropertySources propertySources = configurableEnvironment.getPropertySources();
Properties properties = loadProperties(file);
System.out.println(properties.toString());
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);
}
}
}

5. classpath定义spring.factories文件

org.springframework.boot.env.EnvironmentPostProcessor=com.hlz.web.common.config.MyEnvironmentPostProcessor



6. 如果同一个参数, application.yml中有定义, 外部配置文件也有定义, 以哪一个为准呢,

//以配置文件为准
propertySources.addFirst(new PropertiesPropertySource("Config", properties));
//以application.yml中的文件为准
propertySources.addLast(new PropertiesPropertySource("Config", properties));



7.官网关于EnvironmentPostProcessor的说明



Allows for customization of the application's Environment prior to the application context being refreshed.

EnvironmentPostProcessor implementations have to be registered in META-INF/spring.factories, using the fully qualified name of this class as the key.

EnvironmentPostProcessor processors are encouraged to detect whether Spring's Ordered interface has been implemented or if the @Order annotation is present and to sort instances accordingly if so prior to invocation.



升级版的属性读取解析器:

package com.kiiik.config;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.StringUtils;
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {
/* -Dprotect.config.dir=d:/data/test
* -Dspring.config.location=d:/data/test
* */
String baseFileName= "application.properties";
@Override
public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment, SpringApplication application) {
String selfDefinedDir = System.getProperty("project.config.dir");
String springConfigDir= System.getProperty("protect.config.dir");
String tomcatHome = null;
String configFileDir="";
if(!StringUtils.isEmpty(springConfigDir))//启动参数获取目录,只要指定 肯定有。
{
configFileDir = springConfigDir;//优先级最高100
}else{
if(!StringUtils.isEmpty(selfDefinedDir)){//优先级 99
configFileDir = selfDefinedDir;
}
}
if(configFileDir == null){//没有自定义目录
// tomcat路径
if(!StringUtils.isEmpty(System.getProperty("catalina.home"))){
tomcatHome = System.getProperty("catalina.home");//优先级98
String projectName = System.getProperty("project.name");
if(StringUtils.isEmpty(projectName))
try {
throw new Exception("工程名不能为空,请添加-Dproject.name属性");
} catch (Exception e) {
e.printStackTrace();
}
String relativePath = File.separator + projectName + File.separator ;
configFileDir = tomcatHome+relativePath;
}else{//tomcat也没有定义默认目录,读取工程目录同级的配置文件
String projectName = System.getProperty("project.name");
if(StringUtils.isEmpty(projectName))
try {
throw new Exception("工程名不能为空,请添加-Dproject.name属性");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//读取应用同级目录下的工程名目录下的配置文件
configFileDir = System.getProperty("user.dir") + File.separator+projectName+ File.separator;//读取应用同级目录下的工程名目录下的配置文件
File[] proDirfiles = new File(configFileDir).listFiles();
if(proDirfiles.length==0){//优先级97
//classpath目录下配置文件
File clsPath;
try {
clsPath = org.springframework.util.ResourceUtils.getFile("classpath:");
configFileDir = clsPath.getAbsolutePath()+ File.separator;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//优先级96
}
}
}
if(!configFileDir.endsWith("/")&&!configFileDir.endsWith("\\")){
configFileDir = configFileDir.concat(File.separator);
}
System.out.println("configFileDir:" + configFileDir);
MutablePropertySources propertySources = configurableEnvironment.getPropertySources();
Properties appProperties = loadProperties(new File(configFileDir+baseFileName));
propertySources.addFirst(new PropertiesPropertySource("Config", appProperties));
File[] files = new File(configFileDir).listFiles();
if(files.length ==0)
try {
throw new Exception("没有发现配置文件!");
} catch (Exception e) {
e.printStackTrace();
}
for(int i=0;i<files.length;i++){
if(files[i].getName().contains("properties")&&!baseFileName.equals(files[i].getName())){
System.out.println("load setting file :"+files[i]);
propertySources.addFirst(new PropertiesPropertySource(files[i].getName(), loadProperties(new File(configFileDir+files[i].getName()))));
}
}
}
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);
}
}
}



用户头像

我们始于迷惘,终于更高的迷惘. 2020.03.25 加入

一个酷爱计算机技术、健身运动、悬疑推理的极客狂人,大力推荐安利Java官方文档:https://docs.oracle.com/javase/specs/index.html

评论

发布
暂无评论
SpringBoot-技术专题-war包部署读取外部配置Properties