Spring云配置刷新后如何执行自定义逻辑?
Posted
技术标签:
【中文标题】Spring云配置刷新后如何执行自定义逻辑?【英文标题】:How can I execute custom logic after Spring cloud configuration refresh? 【发布时间】:2018-05-23 00:01:09 【问题描述】:我已将我的应用程序设置为使用 Spring 云配置来提供配置并启用监视器,以便配置服务器将更改事件发布到我的应用程序。配置已正确更新,但我希望在配置更改时收到通知,以便我可以根据新配置执行一些自定义逻辑。
我有这个配置对象
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "my.prefix")
public class MyConfig
private Map<String, MyObject> configs;
private String someValue;
public Map<String, MyObject> getConfigs()...
public void setConfigs()...
public String getSomeValue()...
public void setSomeValue()...
...
public class MyObject
private String field1;
public String getField1() ...
public void setField1() ...
这在我的配置服务器 application.yml 中
my:
prefix:
configs:
TEST:
field1: "testValue"
someValue: "test"
现在,当我在配置中更改 someValue 并且配置服务器发布刷新时,它会调用 setSomeValue() 并将值更新为新值。我可以将我的自定义逻辑添加到 setSomeValue() 并且它会正常工作。但是,在从配置中更新或添加/删除条目时,它似乎没有调用 setConfigs() 或 setField1()。
我尝试为 EnviornmentChangeEvents、RefreshEvents 或 RefreshScopeRefreshedEvents 注册一个侦听器,但这些侦听器要么在 Spring 更新值之前触发,要么根本不触发。我还尝试向 @PreDestroy 和 @PostConstruct 方法添加逻辑,但只有 PreDestroy 最终被调用,并且在配置更新之前被调用。我也尝试实现 InitializingBean 并将我的逻辑放入 afterPropertiesSet() 但它也从未被调用过。
如何在此配置更新时收到通知?
【问题讨论】:
【参考方案1】:使用 RefreshScopeRefreshedEvent 侦听器,您可以在配置更新时收到通知。
以下示例适用于我:
配置:
@Configuration
public class Config
@Bean
@RefreshScope
public A aBean()
return new A();
@Bean
public RefreshScopeRefreshedListener remoteApplicationEventListener(A aBean)
return new RefreshScopeRefreshedListener(aBean);
而听众:
public class RefreshScopeRefreshedListener implements ApplicationListener<RefreshScopeRefreshedEvent>
private A aBean;
public RefreshScopeRefreshedListener(A abean)
this.aBean = abean;
@Override
public void onApplicationEvent(RefreshScopeRefreshedEvent event)
System.out.println(aBean.getValue());
它总是打印配置的新值。
如果你已经尝试过这个监听器,你确定它已经注册好了吗? bean 是否已正确创建?
【讨论】:
这肯定会起作用,但是即使对于其他属性更改它也总是会触发该方法,我认为 RefreshScopeRefreshedEvent 中缺少的是 EnvironmentChangeEvent 可以提供的 getKeys() 方法,但是 EnvironmentChangeEvent 不保证bean @Refreshscope 已更新【参考方案2】:我所做的是获取EnvironmentChangeEvent
监听器的钩子,然后从Environment
本身而不是@Autowired Bean bean
获取更新的属性
@Autowired
private Environment env;
@EventListener(EnvironmentChangeEvent.class)
public void onApplicationEvent(EnvironmentChangeEvent environmentChangeEvent)
log.info("Received an environment changed event for keys ", environmentChangeEvent.getKeys());
if(environmentChangeEvent.getKeys().contains("key.i.wanted.to.recalculate"))
String newValue = env.getProperty("key.i.wanted.to.recalculate");
System.out.println("New Value: " + newValue);
【讨论】:
【参考方案3】:或者,您可以使用@ConfigurationProperties 添加@PostConstruct,以便您可以编写自定义逻辑
@ConfigurationProperties(prefix = "dummy.just.to.trigger.actuator.refresh")
Class AnyPropLoader
@PostConstruct
private void customLogicMethod()
...
【讨论】:
以上是关于Spring云配置刷新后如何执行自定义逻辑?的主要内容,如果未能解决你的问题,请参考以下文章
spring boot整合 spring security之自定义退出
企业分布式微服务云SpringCloud SpringBoot mybatis (十九)Spring Boot 自定义配置文件