I want to change the value of application.yaml
at loading time.
ex) application.yaml
user.name: ${name}
Here, I want to put this value by calling an external API such as a vault, rather than a program argument when the jar is executed with the name value.
First of all, I think I need to write code that implements EnvironmentPostProcessor
and calls external API, but I don't know how to inject that value. can I get help?
public class EnvironmentConfig implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
// API CAll
// how can inject yaml value??
}
}
I don't know which way to orient myself.
CodePudding user response:
OPTION 1: doing it via EnvironmentPostProcessor:
assuming you have registered you EnvironmentPostProcessor in /resources/META-INF/spring.factories
file:
org.springframework.boot.env.EnvironmentPostProcessor=package.to.environment.config.EnvironmentConfig
all you need is to add your custom PropertySource:
public class EnvironmentConfig implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
environment.getPropertySources()
.addFirst(new CustomPropertySource("customPropertySource"));
}
}
public class CustomPropertySource extends PropertySource<String> {
public CustomPropertySource(String name) {
super(name);
}
@Override
public Object getProperty(String name) {
if (name.equals("name")) {
return "MY CUSTOM RUNTIME VALUE";
}
return null;
}
}
OPTION 2: doing it via PropertySourcesPlaceholderConfigurer:
A class that is responsible for resolving these palceholders is a BeanPostProcessor called PropertySourcesPlaceholderConfigurer
(see here).
So you could override it and provide you custom PropertySource
that would resolve your needed property like so:
@Component
public class CustomConfigurer extends PropertySourcesPlaceholderConfigurer {
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, ConfigurablePropertyResolver propertyResolver) throws BeansException {
((ConfigurableEnvironment) beanFactoryToProcess.getBean("environment"))
.getPropertySources()
.addFirst(new CustomPropertySource("customPropertySource"));
super.processProperties(beanFactoryToProcess, propertyResolver);
}
}
CodePudding user response:
use ConfigurationProperties
for your properties and change it via an api like this:
@Component
@ConfigurationProperties(prefix = "user")
public class AppProperties {
private String name;
//getter and setter
}
@RestController
public class AppPropertiesController {
@Autowire
AppProperties prop;
@PostMapping("/changeProp/{name}")
public void change(@PathVariable String name){
prop.setName(name);
}
}