springboot加載外部配置文件-war包直接讀取外部配置文件


https://blog.csdn.net/iechenyb/article/details/102777704

 
1. springboot支持動態的讀取文件,擴展接口:org.springframework.boot.env.EnvironmentPostProcessor

我的項目使用場景起因是: 在同一台機器上起了兩個tomcat實例, 每個項目的日志文件打印路徑要配成不同, 如果每次打包手動修改打印日志的路徑太費時費力, 所以考慮把配置文件每個tomcat放一份, 啟動時自動讀取當前tomcat文件下的配置就好.

2. 我這里的自定義配置文件存放路徑: tomcat的conf文件夾下面

3. application.properties配置文件內容(我這里不同tomcat配置參數值不同)

spring.profiles.active=test
4. 定義MyEnvironmentPostProcessor實現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定義一個META-INF文件夾然后在其下面先建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);
}
}
}

———————————————— 
原文鏈接:https://blog.csdn.net/iechenyb/article/details/102777704


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM