这是我使用 Spring Boot 2.1.5 提出的一个 hacky 解决方案。使用自定义PropertyResolver可能更好
本质上它是这样的:
- 抓住
PropertySource
我在乎的。对于这种情况,它是application.properties
. 应用程序可以有N
多个来源,因此如果还有其他<< >>
可能出现的地方,那么您也要检查它们。
- 循环遍历源的值
<< >>
- 如果匹配,则动态替换该值。
我的属性是:
a=hello from a
b=<<I need special attention>>
我的黑客ApplicationListener
是:
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
public class EnvironmentPrepareListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
private final RestTemplate restTemplate = new RestTemplate();
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
// Only focused main application.properties (or yml) configuration
// Loop through sources to figure out name
final String propertySourceName = "applicationConfig: [classpath:/application.properties]";
PropertySource<?> propertySource = event.getEnvironment().getPropertySources()
.get(propertySourceName);
Map<String, Object> source = ((OriginTrackedMapPropertySource) propertySource).getSource();
Map<String, Object> myUpdatedProps = new HashMap<>();
final String url = "https://jsonplaceholder.typicode.com/todos/1";
for (Map.Entry<String, Object> entry : source.entrySet()) {
if (isDynamic(entry.getValue())) {
String updatedValue = restTemplate.getForEntity(url, String.class).getBody();
myUpdatedProps.put(entry.getKey(), updatedValue);
}
}
if (!myUpdatedProps.isEmpty()) {
event.getEnvironment().getPropertySources()
.addBefore(
propertySourceName,
new MapPropertySource("myUpdatedProps", myUpdatedProps)
);
}
}
private boolean isDynamic(Object value) {
return StringUtils.startsWith(value.toString(), "<<")
&& StringUtils.endsWith(value.toString(), ">>");
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
击球/test
让我:
{ "userId": 1, "id": 1, "title": "delectus aut autem", "completed": false }