通过监听器方式监听配置是否发生变化,发生变化后进行更新(创建事件处理器->发布事件->监听事件)
-
创建配置变更事件类
点击查看代码
import org.springframework.context.ApplicationEvent;
import java.util.Properties;
/**
* @author crazy
* @describe 配置变更事件
* @date 2023/4/13 15:11
*/
public class PropertiesChangeEven extends ApplicationEvent {
/**
* 变更配置(需要变更的配置)
*/
private Properties properties;
/**
* 旧配置项(配置项原参数)
*/
private Properties oldProperties;
/**
* 新配置项(配置项新参数)
*/
private Properties newProperties;
public PropertiesChangeEven(Properties source) {
super(source);
this.properties = source;
}
@Override
public Properties getSource() {
return properties;
}
public Properties getOldProperties() {
return oldProperties;
}
public void setOldProperties(Properties oldProperties) {
this.oldProperties = oldProperties;
}
public Properties getNewProperties() {
return newProperties;
}
public void setNewProperties(Properties newProperties) {
this.newProperties = newProperties;
}
}
-
创建配置变更处理
点击查看代码
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.stereotype.Service;
import java.util.Enumeration;
import java.util.Properties;
/**
* @author crazy
* @describe 配置变更处理
* @date 2023/4/13 16:53
*/
@Slf4j
@Service
public class PropertiesChangeHandle {
/**
* 配置项
*/
@Autowired
private ConfigurableEnvironment configurableEnvironment;
/**
* 监听器事件发布器
*/
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
/**
* 配置变更
* @param properties
* @return void
* @modify
*/
public void changeProperties(Properties properties){
if (properties == null){
return;
}
log.info("通过使用@EventListener注解或实现ApplicationListener接口监听配置变更");
Properties oldProperties = new Properties();
Properties newProperties = new Properties();
Enumeration enumeration = properties.propertyNames();
while(enumeration.hasMoreElements()){
String keyName = (String) enumeration.nextElement();
// 旧参数
Object oldValue = configurableEnvironment.getProperty(keyName);
// 新参数
Object newValue = properties.getProperty(keyName);
if (oldValue != null){
oldProperties.put(keyName, oldValue);
}
if (newValue != null && !newValue.equals(oldValue)){
newProperties.put(keyName, newValue);
}
}
PropertiesChangeEven propertiesChangeEven = new PropertiesChangeEven(properties);
propertiesChangeEven.setOldProperties(oldProperties);
propertiesChangeEven.setNewProperties(newProperties);
// 发布配置变更事件
applicationEventPublisher.publishEvent(propertiesChangeEven);
}
}
-
监听配置变更事件,实现ApplicationListener接口或实现@EventListener注解
点击查看代码
import com.crazy.practice.boot.even.PropertiesChangeEven;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author crazy
* @describe 配置变更事件监听器
* @date 2023/4/13 15:12
*/
@Slf4j
@Component
public class PropertiesChangeListener implements ApplicationListener<PropertiesChangeEven>, ApplicationContextAware {
private ApplicationContext applicationContext;
/**
* 配置刷新
*/
@Autowired(required = false)
private ContextRefresher contextRefresher;
@Override
public void onApplicationEvent(PropertiesChangeEven propertiesChangeEven) {
log.info("通过实现ApplicationListener.onApplicationEvent监听配置变更");
Map propertiesMap = propertiesChangeEven.getNewProperties();
ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) applicationContext.getEnvironment();
MutablePropertySources mutablePropertySources = configurableEnvironment.getPropertySources();
mutablePropertySources.addFirst(new MapPropertySource("refreshProperties", propertiesMap));
// 刷新配置项
contextRefresher.refresh();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
或
点击查看代码
import com.crazy.practice.boot.even.PropertiesChangeEven;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
* @author crazy
* @describe 配置变更事件监听器
* @date 2023/4/13 15:59
*/
@Slf4j
@Component
public class PropertiesChangeListener2 {
@EventListener(PropertiesChangeEven.class)
public void propertiesListener(PropertiesChangeEven propertiesChangeEven){
log.info("通过实现@EventListener注解监听配置变更");
log.info("变更配置:{}", propertiesChangeEven.getSource());
log.info("旧配置:{}", propertiesChangeEven.getOldProperties());
log.info("新配置:{}", propertiesChangeEven.getNewProperties());
}
}
-
发布事件,在需要动态刷新配置的类上加上@RefreshScope
点击查看代码
/**
* 监听器事件发布器
*/
@Autowired
private PropertiesChangeHandle propertiesChangeHandle;
/**
* 更新配置项信息
* @param key
* @param value
* @param comments
* @return java.lang.String
*/
@GetMapping("/updateProperties")
public String updateProperties(@RequestParam(value = "key")String key, @RequestParam(value = "value")String value, @RequestParam(value = "comments", required = false)String comments){
Map map = new HashMap();
map.put(key, value);
Properties properties = new Properties();
properties.put(key, value);
propertiesChangeHandle.changeProperties(properties);
return value;
}