SpringBoot如何加载jar包外面的配置文件

SpringBoot如何加载jar包外面的配置文件

两种情况:

1.在填充普通bean属性之前加载

2.在初始化之后,填充普通bean属性加载

3.通过System.setProperty() 来设置获取

先清楚一个问题:扫描策略(涉及到覆盖优先级问题)

配置文件位置及加载顺序
SpringBoot 项目中的application.properties配置文件一共可以出现在如下4个位置:
顺序:高-》低

项目根目录下的config文件夹
项目根目录下
classpath下的config文件夹
classpath下

优先级由高到底,高优先级的配置会覆盖低优先级的配置;

SpringBoot会从这四个位置全部加载主配置文件;互补配置;

我们还可以通过spring.config.location来改变默认的配置文件位置
在运行时再指定配置文件的名字。使用spring.config.location可以指定配置文件所在目录
指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=G:/application.properties

情况1 :在填充普通bean属性之前加载

springBoot的EnvironmentPostProcessor使用

SpringBoot支持动态的读取文件,留下的扩展接口org.springframework.boot.env.EnvironmentPostProcessor。这个接口是spring包下的,使用这个进行配置文件的集中管理,而不需要每个项目都去配置配置文件。这种方法也是springboot框架留下的一个扩展(可以自己去扩展)

使用步骤

介绍:即在加载resource 下的application.yml文件之前加载外部文件到环境中environment

步骤一:

/**
 *
 *自定义环境处理,在运行SpringApplication之前加载任意配置文件到Environment环境中
 * @author sunrj
 * @create 2021-07-06 13:48
 */
public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor,Ordered {

    private static final Integer POST_PROCESSOR_ORDER = Integer.MAX_VALUE+10;

    @Override
    public int getOrder() {
        return -this.POST_PROCESSOR_ORDER;
    }

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment,SpringApplication application) {

        //自定义配置文件
          //自定义配置文件
        String[] profiles = {
                "xxx.properties",
                "yyy.properties",
                "zzz.yml",
        };

        //循环添加
        for (String profile : profiles) {
            //从classpath路径下面查找文件
           // Resource resource = new ClassPathResource(profile);
           //从自定义文件夹下找
            Resource resource = new PathResource("/adc-cms/repository/"+profile);
          
            //加载成PropertySource对象,并添加到Environment环境中
            environment.getPropertySources().addLast(loadProfiles(resource));
        }
    }

    //加载单个配置文件
    private PropertySource<?> loadProfiles(Resource resource) {
        if (!resource.exists()) {
            throw new IllegalArgumentException("资源" + resource + "不存在");
        }
        try {
            YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
            List<PropertySource<?>> propertySources = sourceLoader.load(resource.getFilename(), resource);
            return propertySources.get(0);

        }catch (IOException ex) {
            throw new IllegalStateException("加载配置文件失败" + resource, ex);
        }

    }


}

步骤二、
接口的实现类必须在META-INF/spring.factories文件中注册,使用EnvironmentPostProcessor 的全类名当key,实现类的全类名当value。resources目录下新建META-INF/spring.factories文件,添加如下内容。

在\resources\META-INF\spring.factories添加:

## 启用我们的自定义环境处理类
org.springframework.boot.env.EnvironmentPostProcessor=com.confs.config.CustomEnvironmentPostProcessor

在启动类中测试运行:

@SpringBootApplication
public class Application {
	public static void main(String[] args) {
		ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
		System.out.println(context.getEnvironment().getProperty("file.property"));
		System.out.println(context.getEnvironment().getProperty("file.list"));
		context.close();
	}
}

情况2:在初始化之后,填充普通bean属性加载

@PropertySource能够“扫描”和加载jar包外面的properties文件,但扫描不到yml

yml做法:

@ConfigurationProperties(prefix = "admin")
@Configuration
@NoArgsConstructor
@Getter
@Setter
public class AdminAuthProperties {

    private AuthMethod[] loginMethodLimit;

    private AccountLockingPolicyProperties lockingPolicy;

    private List<String> loginNameFields;

    private String publicKey;

    private String privateKey;


//加载外部配置
    @Bean
    public static PropertySourcesPlaceholderConfigurer loadProperties() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
        yaml.setResources(new PathResource("./repository/cms.yml"));//class路径引入
        configurer.setProperties(yaml.getObject());
        return configurer;
    }
}

properties做法:

通过@PropertySource注解将properties配置文件中的值存储到Spring的 Environment中,Environment接口提供方法去读取配置文件中的值,参数是properties文件中定义的key值。

在@ConfigurationProperties注释中有两个属性:
locations:指定配置文件的所在位置
prefix:指定配置文件中键名称的前缀(我这里配置文件中所有键名都是以author.开头)

使用@Component是让该类能够在其他地方被依赖使用,即使用@Autowired注释来创建实例。

创建测试Controller
@PropertySource和@Value

创建java配置类

@Configuration
@PropertySource(value = {
        "classpath:xxx.properties",
        "classpath:yyy.properties",
        "classpath:zzz.yml",},encoding = "utf-8")
public class PropertiesWithJavaConfig {
   @Value(${jdbc.driver})
   private String driver;
   @Value(${jdbc.url})
   private String url;
   @Value(${jdbc.username})
   private String username;
   @Value(${jdbc.password})
   private String password;
   //要想使用@Value 用${}占位符注入属性,这个bean是必须的,这个就是占位bean,另一种方式是不用value直接用Envirment变量直接getProperty('key')  
   @Bean
   public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
      return new PropertySourcesPlaceholderConfigurer();
   }
}

情况3:通过System.setProperty() 来设置获取

可在启动类中,把需要加载的文件通过以下方式存起来:

System.setProperty(固定值,加载的文件路径)

System.setProperty("spring.config.location","D:\\project\\other-project\\\repository\\application.yml");
System.setProperty("Property2","def");
//这样就把第一个参数设置成为系统的全局变量!可以在项目的任何一个地方 通过System.getProperty("变量");来获得,
//System.setProperty 相当于一个静态变量  ,存在内存里面!
 
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值