spring 如何在Sping Boot 中在运行时注入应用程序yaml值?

mxg2im7a  于 2022-11-21  发布在  Spring
关注(0)|答案(2)|浏览(131)

我想在加载时更改application.yaml的值。
ex)应用程序.yaml

user.name: ${name}

在这里,我想通过调用一个外部API(如vault)来放置这个值,而不是在使用name值执行jar时使用程序参数。
首先,我想我需要编写实现EnvironmentPostProcessor并调用外部API的代码,但我不知道如何注入该值。

public class EnvironmentConfig implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment,
        SpringApplication application) {
        // API CAll
        
        // how can inject yaml value??
    }
}

我不知道该往哪走。

ogq8wdun

ogq8wdun1#

选项1:通过环境后处理器执行:

假设您已在/resources/META-INF/spring.factories文件中注册了EnvironmentPostProcessor:
org.springframework.boot.env.EnvironmentPostProcessor=package.to.environment.config.EnvironmentConfig
您所需要的只是添加自定义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;
    }
}

选项2:通过属性资源占位符配置器执行此操作:

负责解析这些占位符的类是名为PropertySourcesPlaceholderConfigurer的BeanPostProcessor(请参见here)。
因此,您可以覆盖它并提供自定义的PropertySource,它将解析您所需的属性,如下所示:

@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);
    }
}
8xiog9wr

8xiog9wr2#

使用ConfigurationProperties作为你的属性,并通过一个api修改它,如下所示:

@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);
    }
}

相关问题