Springboot加载外部配置文件的方法

1. 项目内部配置文件


    

以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。

SpringBoot会从这四个位置全部加载主配置文件,如果高优先级中配置文件属性与低优先级配置文件不冲突的属性,则会共同存在—互补配置。

对于Spring Boot项目加载外部配置文件,有两种做法可以实现该目的:

1.1. --spring.config.location

--spring.config.location="D:/xxx/system.properties"

要特别注意的是,该命令指定的配置文件会使项目默认的application.properties或application.yml文件失效,换句话说该命令会用指定的配置文件替换application.properties或application.yml文件。

java -jar spring-boot-SNAPSHOT.jar --spring.config.location=file:///D:/application.properties,classpath:/,classpath:/config/
项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置。

指定配置文件和默认加载的这些配置文件共同起作用形成互补配置。
Idea 单测启用自定义配置:添加jvm参数:-Dspring.config.location=file:///D:/project_conf/application.yml -ea

1.2. --spring.config.additional-location

--spring.config.additional-location="D:/xxx/system.properties"

顾名思义,该命令用于追加配置文件。原有的application.properties或application.yml文件均有效。

Spring提供了profiles的概念可以帮助我们进行多环境的配置,首先看下类ConfigFileApplicationListener的getSearchLocations

// Note the order is from least to most specific (last one wins)
private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";
public static final String CONFIG_LOCATION_PROPERTY = "spring.config.location";
public static final String CONFIG_ADDITIONAL_LOCATION_PROPERTY = "spring.config.additional-location";

private Set<String> getSearchLocations() {
   if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) {
      return getSearchLocations(CONFIG_LOCATION_PROPERTY);
   }
   Set<String> locations = getSearchLocations(
         CONFIG_ADDITIONAL_LOCATION_PROPERTY);
   locations.addAll(
         asResolvedSet(ConfigFileApplicationListener.this.searchLocations,
               DEFAULT_SEARCH_LOCATIONS));
   return locations;
}

从上述代码可以看出,如果有在Environment中指定了 spring.config.location 会只取该项的地址去获取配置文件,若没有指定spring.config.location,配置文件获取优先级为

  1. spring.config.additional-location指定的地址
  2. file:./config/
  3. file:./
  4. classpath:/config/
  5. classpath:/

而spring.config.name、spring.config.location和spring.config.additional-location等配置是从environment中获取的,详情可跳转 Spring Boot官方参考了解更多信息 Application Property Files

上述可以得出,只要在environment(环境变量) 中指定不同的spring.config.additional-location就可以达到war包与配置文件分离的效果,常见形式如下

  • jar包:jar spring-boot-sample-web.jar –spring.config.additional-location=~/config/
  • war包:在tomcat中可以在${TOMCAT_HOME}/conf/catalina.properties末尾添加
    #spring environment property
    spring.config.additional-location=~/config/#配置文件所在文件夹

注意:file:./ 在打成jar包的springboot项目指向jar包所在目录,以war包形式在tomcat中指向startup所在的bin目录,具体可在不同环境中输出 file:./ 对应的绝对路径
new DefaultResourceLoader().getResource(“file:./”).getFile().getAbsolutePath(); 

1.3.文件名问题

对于application.properties而言,它不一定非要叫application,但是项目默认去加载名为application的配置文件,如果我们的配置文件不叫application,也是可以的,但是需要明确指定配置文件的文件名。

方式和指定路径一致,只不过此时key是spring.config.name.

例:首先在resource目录下创建一个app.properties文件,然后再启动配置参数  --spring.config.name=app

2. 外部配置加载顺序

SpringBoot也可以从以下位置加载配置:优先级从高到低;高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置。

1.命令行参数

  • 所有的配置都可以在命令行上进行指定;
  • 多个配置用空格分开; –配置项=值

  java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc

2.来自java:comp/env的JNDI属性 

3.Java系统属性(System.getProperties()) 

4.操作系统环境变量 

5.RandomValuePropertySource配置的random.*属性值

6.jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件

7.jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件

8.jar包外部的application.properties或application.yml(不带spring.profile)配置文件

9.jar包内部的application.properties或application.yml(不带spring.profile)配置文件

10.@Configuration注解类上的@PropertySource ,(yaml文件不支持@PropertySource )。例:

@Configuration
@PropertySource(value = {"file:/xxx/xxx/config/xxxConfig.properties"}, encoding = "utf-8")

11.通过SpringApplication.setDefaultProperties指定的默认属性

3.war包部署读取外部配置.yml文件的方法

当我们使用springboot开发时,有的时候需要打war包在外部tomcat部署,方便运维人员维护,但是修改配置文件后重新打包给运维的时候,又需要修改一些配置这样还是不方便维护。

在网上找了很多例子但是都是针对.properties文件,读取.yml文件会有问题,当我在看关于springboot加载yml文件时发现需要用到其他的类,YamlPropertiesFactoryBean和YamlMapFactoryBean。下面把读取外部.yml配置文件的方法贴出来。

自定义配置类实现EnvironmentPostProcessor接口

  1. EnvironmentPostProcessor是springboot支持动态读取文件的接口,实现EnvironmentPostProcessor接口覆写postProcessEnvironment方法
  2. 在postProcessEnvironment方法实现读取外部配置文件
  3.  使用YamlPropertiesFactoryBean来读取yml配置文件,getObject()方法可以获取Properties

首先我把springboot.yml配置文件放在tomcat目录的conf目录下(可以根据自己需求修改目录)

实现EnvironmentPostProcessor在方法中完成yml配置读取

public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        //tomcat路径
        String property = System.getProperty("catalina.home");
        String path = property + File.separator + "conf" + File.separator + "myapplication.yml";
        //Springboot读取yml配置
        YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
        yaml.setResources(new FileSystemResource(path));
        MutablePropertySources propertySources = environment.getPropertySources();
        propertySources.addFirst(new PropertiesPropertySource("Config", yaml.getObject()));
    }
}


在resouces目录下建一个META-INF文件目录,在目录中建一个spring.factories文件,在文件中配置自己实现的动态读取文件类

org.springframework.boot.env.EnvironmentPostProcessor=com.hzone.demo.config.MyEnvironmentPostProcessor

  
在pom.xml中配置maven打包时移除配置文件

  

最后tomcat启动,springboot启动会加载datasource配置创建'sqlSessionFactory',正序正常启动就说明这种方式读取yml配置文件没有问题。

正常启动,成功加载到了.yml配置文件。

最后说一下logback.xml配置文件丢到外面直接在.yml配置文件中配置好路径就可以了

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值