springboot加载外部配置文件-war包直接读取外部配置文件

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);
		}
	}
}

 

在Spring Boot应用中,如果你想要打WAR并从外部yml配置文件加载配置,你可以按照以下步骤操作: 1. **自定义配置类**[^1]: - 创建一个实现了`org.springframework.boot.context.config.ConfigurationPropertiesBindingPostProcessor`接口的类。这个接口用于处理配置属性绑定到Java对象。 ```java @Configuration public class YamlConfigProcessor implements ConfigurationPropertiesBindingPostProcessor { private final YamlPropertiesFactoryBean factoryBean = new YamlPropertiesFactoryBean(); @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { factoryBean.setResources(new ClassPathResource("config.yml")); // 指定yml文件的位置 factoryBean.load(); environment.getPropertySources().addFirst(factoryBean.getObject()); } } ``` 2. **配置POM.xml**[^2]: - 在构建工具如Maven或Gradle中,确保你的`pom.xml`或`build.gradle`配置了正确的插件和依赖,以便打WAR文件。 Maven示例: ```xml <build> ... <plugins> <!-- Spring Boot war packaging --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> ... </build> ``` 3. **运行应用**: - 使用`mvn clean install package` 或 `gradle build fatJar`命令构建应用,并生成WAR文件。 4. **部署**: - 将生成的WAR文件部署到Tomcat或其他Web服务器上,通常路径会类似`/webapps/your-app-name.war`。 当你部署好应用后,Spring Boot会在启动时自动读取指定位置的`config.yml`文件中的配置。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值