springboot动态刷新配置

通过监听器方式监听配置是否发生变化,发生变化后进行更新(创建事件处理器->发布事件->监听事件)

  1. 创建配置变更事件类

点击查看代码
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;
    }
}
  1. 创建配置变更处理

点击查看代码
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);
    }
}
  1. 监听配置变更事件,实现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());
    }
}
  1. 发布事件,在需要动态刷新配置的类上加上@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;
    }
posted @   土豆泥呀  阅读(583)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示