Spring Boot 加载配置的6种骚操作,第6种知道的人很少

1. 简介

在Spring Boot应用开发中,随着业务复杂度提升及多环境部署需求的增加,传统硬编码配置方式不仅难以维护,还可能导致环境切换时频繁修改代码,增加部署风险。Spring Boot通过外部化配置机制,允许开发者将配置信息从代码中剥离,集中存储在外部文件或系统中,实现配置与代码解耦。

为满足不同场景需求,Spring Boot提供了多种加载自定义配置文件的方式,本篇文章将详细的介绍6种方式加载自定义的外部配置数据。

2.实战案例

2.1 使用命令行

通过命令行配置数据是最直接,简单的方式,我们不需要在代码中做任何的处理直接可以通过 @Value 或者 @ConfigurationProperties 进行读取。如下在启动应用时通过 "--xxx=ooo" 格式进行配置:

java -jar app.jar --pack.app.title=命令行参数xxxooo

测试代码

@Component
public class CommandLineArgumentRunner implements CommandLineRunner {
  @Value("${pack.app.title:}")
  private String title ;


  @Override
  public void run(String... args) throws Exception {
    System.err.printf("Command Line Argument title: %s%n", title) ;
  }
}

输出结果

Command Line Argument title: 命令行参数xxxooo

2.2 使用spring.config.import

通过 spring.config.import 配置属性可以非常方便的导入类路径或文件系统中的配置文件,导入后无需进行任何其它处理就可以使用了。如下配置:

spring:
  config:
    import:
    - optional:file:/d:/pack/config.properties

config.properties配置文件

测试代码

@Component
public class ConfigImportRunner implements CommandLineRunner {
  @Value("${pack.app.title:}")
  private String title ;


  @Override
  public void run(String... args) throws Exception {
    System.err.printf("spring.config.import title: %s%n", title) ;
  }
}

输出结果

spring.config.import title: 通过spring.config.import导入外部文件-001

2.3 使用@PropertySource

通过该注解同样可以加载类路径下或者磁盘文件中的配置文件,但是通过该注解有一个限制是不能加载yaml格式的文件,需要自定义PropertySourceFactory实现加载逻辑。如下配置:

@Component
@PropertySource(
    value = {"classpath:pack.properties", "file:/d:/pack/other.properties"},
    encoding = "UTF-8")
public class PackConfig {
}

这里加载了类路径及文件系统中的配置文件。

配置文件内容如下:

#pack.properties
pack.app.version=1.0.0
#other.properties
pack.app.author=pack

测试代码

@Component
public class PropertySourceRunner implements CommandLineRunner {
  @Value("${pack.app.version}")
  private String version ;
  @Value("${pack.app.author}")
  private String author ;


  @Override
  public void run(String... args) throws Exception {
    System.err.printf("version: %s, author: %s%n", version, author) ;
  }
}

输出结果

version: 1.0.0, author: pack

2.4 自定义EnvironmentPostProcessor

允许在应用上下文刷新(refresh)之前对应用程序的 Environment 进行自定义。

EnvironmentPostProcessor 的实现类需要在 META-INF/spring.factories 文件中注册,使用该类的全限定名作为键(key)。如果希望以特定顺序调用这些实现类,可以让它们实现 Ordered 接口或使用 @Order 注解。如下自定义实现:

public class PackEnvironmentPostProcessor implements EnvironmentPostProcessor {
  private final PropertiesPropertySourceLoader loader = new PropertiesPropertySourceLoader();
  @Override
  public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
    Resource resource = new FileSystemResource(new File("d:/pack/xg.properties")) ;
    try {
      environment.getPropertySources().addFirst(loader.load("xg", resource).getFirst()) ;
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

配置文件内容如下:

pack.app.env=prod

接下来,在META-INF/spring.factories中定义

org.springframework.boot.env.EnvironmentPostProcessor=\
com.pack.way4.postprocessor.PackEnvironmentPostProcessor

测试代码

@Component
public class EnvPostProcessorRunner implements CommandLineRunner {
  @Value("${pack.app.env}")
  private String env ;


  @Override
  public void run(String... args) throws Exception {
    System.err.printf("env: %s%n", env) ;
  }
}

输出结果

env: prod

2.5 使用@TestPropertySource

通过名称应该能猜到,该注解是应用在测试环境中,如下代码:

@SpringBootTest
@TestPropertySource("file:/d:/pack/test.properties")
public class AppTest {
  @Value("${pack.app.ocr}")
  private String ocr ;


  @Test
  public void testLoadConfig() {
    System.err.println(ocr) ;
  }
}

配置文件内容如下:

pack.app.ocr=xxxooo

运行测试用例,输出结果

xxxooo

2.6 自定义PropertySourceLocator

该接口并不是Spring Boot中提供,而是Spring Cloud,所以我们首先要引入如下依赖:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-context</artifactId>
  <version>4.2.1</version>
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-bootstrap</artifactId>
  <version>4.2.1</version>
</dependency>

自定义Locator

@Configuration
public class PackPropertySourceLocator implements PropertySourceLocator {
  @Override
  public PropertySource<?> locate(Environment environment) {
    return new MapPropertySource("packxg", Map.of("pack.app.vendor", "xg_pack"));
  }
}

接下来,还需要在META-INF/spring.factories中进行配置

org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.pack.way5.propertysourcelocator.PackPropertySourceLocator

测试代码

@Component
public class LocatorRunner implements CommandLineRunner {
  @Value("${pack.app.vendor}")
  private String vendor ;
  @Override
  public void run(String... args) throws Exception {
    System.err.printf("pack.app.vendor: %s%n", vendor) ;
  }
}

输出结果

pack.app.vendor: xg_pack
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值