springboot2 关于项目配置文件的各种玩儿法

application.properties配置文件是springboot默认的加载文件,但是在现实研发过程中,默认的配置形式无法满足实际的需求,因此对有关配置的问题进行一次整理,主要包括:springboot默认扫描顺序、区分环境加载的两种方式、启动参数指定形式加载、自定义文件如何加载、配置如何拆分等。

一、application.properties配置文件存放位置及加载顺序

application.properties配置文件作为默认启动配置,在springboot项目中共有四个位置可以存放:

  1. 当前项目根目录config下:/config/
  2. 当前项目目录下:/
  3. resources目录config下:/resources/config/
  4. resources目录下:/resources/

其加载默认扫描优先级按照上边四种的排列顺序依次扫描
/config/ >/ > /resources/config/ > /resources/
当遇到重复的参数时,默认以第一次加载的为准

二、区分运行环境加载指定配置

  1. 最简单的一种就是application.properties中加入spring.profiles.active参数,然后新建不同环境下需要分别指定的文件,例如,以区分研发、测试、生产环境为例
    | - application.properties
    | - application-dev.properties
    | - application-test.properties
    | - application-prod.properties

application中加入spring.profiles.active=dev或者test、prod即可;不能同时设置

  1. 在启动参数中指定

java -jar --spring.profiles.active=dev XXX.jar

  1. 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接口在项目启动时加载指定的配置文件

  1. 项目代码目录新建包configuration,然后新建类ExternalProperties
  2. 在 /resources/META-INF/ 下新建文件spring.factories,内容:

org.springframework.boot.env.EnvironmentPostProcessor=com.XXX.configuration.ExternalProperties

  1. 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值