虽然它们有效,但我认为最重要的答案中的方法有点脆弱,因为它只适用于预定义的名称,并且会默默地停止检查当有人在配置中更改 quartz.datasource.url 以使用不同的展开。
理想情况下,我希望 this value of ignoreUnresolvablePlaceholders 成为 false 以便在解析我的配置(例如 application.properties 或其 YAML 变体)时进行批量扩展检查,但 it's hard-coded to true 用于这些情况。不幸的是,如果找不到FOO,这会使诸如${FOO} 之类的字符串处于未扩展的形式,从而使故障排除变得非常痛苦。对于密码等不容易出现在日志中的字段尤其如此。
虽然除了修改 Spring Boot 的类之外我找不到更改 ignoreUnresolvablePlaceholders 的方法,但我确实找到了使用自定义 PropertySource 实现并定义新语法(例如“${!FOO}”)的替代方法来指示FOO 必须作为环境变量存在,否则就会死掉。 (OP没有提到my.home是否是环境变量,但下面的代码是针对环境变量的。)
首先,注册自定义PropertySource 需要一个EnvironmentPostProcessor 实现。这个StrictSystemEnvironmentProcessor.java 做到了这一点,并拥有自定义PropertySource 的实现:
package some.package;
@Order(Ordered.LOWEST_PRECEDENCE)
class StrictSystemEnvironmentProcessor implements EnvironmentPostProcessor {
private static final String PROPERTY_SOURCE_NAME = "STRICT_" + StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
if (environment.getPropertySources().contains(PROPERTY_SOURCE_NAME)) {
return;
}
SystemEnvironmentPropertySource delegate = (SystemEnvironmentPropertySource)environment.getPropertySources()
.get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
environment.getPropertySources().addLast(new StrictSystemEnvironmentPropertySource(delegate));
}
private static class StrictSystemEnvironmentPropertySource extends SystemEnvironmentPropertySource {
public StrictSystemEnvironmentPropertySource(SystemEnvironmentPropertySource delegate) {
super(PROPERTY_SOURCE_NAME, delegate.getSource());
}
@Override
public Object getProperty(String name) {
if (name.startsWith("!")) {
String variableName = name.substring(1);
Object property = super.getProperty(variableName);
if (property != null) {
return property;
}
throw new IllegalStateException("Environment variable '" + variableName + "' is not set");
}
return null;
}
}
}
不是返回null,而是为以! 开头的名称引发异常。
这个META-INF/spring.factories也是必需的,以便Spring初始化我们的EnvironmentPostProcessor:
org.springframework.boot.env.EnvironmentPostProcessor=some.package.StrictSystemEnvironmentProcessor
然后,我可以在我的配置中将所有环境变量替换写为${!FOO} 以进行严格的存在性检查。