|
@@ -1,17 +1,28 @@
|
|
|
package com.chelvc.framework.nacos.config;
|
|
|
|
|
|
-import java.util.Collections;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
|
|
|
+import ch.qos.logback.classic.Level;
|
|
|
+import ch.qos.logback.classic.Logger;
|
|
|
+import ch.qos.logback.classic.LoggerContext;
|
|
|
import com.alibaba.nacos.api.common.Constants;
|
|
|
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
|
|
|
import com.alibaba.nacos.spring.context.event.config.NacosConfigReceivedEvent;
|
|
|
+import com.chelvc.framework.base.context.LoggingContextHolder;
|
|
|
+import com.chelvc.framework.common.util.ObjectUtils;
|
|
|
import com.chelvc.framework.nacos.context.NacosContextHolder;
|
|
|
+import com.google.common.collect.Maps;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.InitializingBean;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
|
|
|
import org.springframework.context.ApplicationContext;
|
|
|
import org.springframework.context.ApplicationListener;
|
|
|
import org.springframework.context.annotation.Configuration;
|
|
|
+import org.springframework.core.env.ConfigurableEnvironment;
|
|
|
+import org.springframework.core.env.PropertySource;
|
|
|
|
|
|
/**
|
|
|
* Nacos配置中心配置
|
|
@@ -25,12 +36,73 @@ import org.springframework.context.annotation.Configuration;
|
|
|
groupId = "${nacos.config.group:" + Constants.DEFAULT_GROUP + "}", autoRefreshed = true)
|
|
|
@NacosPropertySource(dataId = "${nacos.config.id:${spring.application.name}}",
|
|
|
groupId = "${nacos.config.group:" + Constants.DEFAULT_GROUP + "}", autoRefreshed = true)
|
|
|
-public class NacosConfigConfigurer implements ApplicationListener<NacosConfigReceivedEvent> {
|
|
|
+public class NacosConfigConfigurer implements InitializingBean, ApplicationListener<NacosConfigReceivedEvent> {
|
|
|
private final ApplicationContext applicationContext;
|
|
|
+ private final Map<String, Object> properties = Maps.newHashMap();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重置Logger日志级别
|
|
|
+ *
|
|
|
+ * @param name Logger名称
|
|
|
+ * @param level 日志级别
|
|
|
+ */
|
|
|
+ private void resetLoggerLevel(String name, String level) {
|
|
|
+ if (!name.startsWith(LoggingContextHolder.LOGGING_LEVEL_PREFIX)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ name = name.substring(LoggingContextHolder.LOGGING_LEVEL_PREFIX.length());
|
|
|
+ LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
|
|
|
+ Logger logger = context.getLogger(name);
|
|
|
+ if (logger != null) {
|
|
|
+ logger.setLevel(ObjectUtils.ifNull(level, Level::toLevel));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public synchronized void afterPropertiesSet() throws Exception {
|
|
|
+ // 初始化Nacos当前配置,并根据配置重置日志级别
|
|
|
+ ConfigurableEnvironment environment = (ConfigurableEnvironment) this.applicationContext.getEnvironment();
|
|
|
+ for (PropertySource<?> source : environment.getPropertySources()) {
|
|
|
+ if (!(source instanceof com.alibaba.nacos.spring.core.env.NacosPropertySource)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Map<String, ?> properties = ((com.alibaba.nacos.spring.core.env.NacosPropertySource) source).getSource();
|
|
|
+ if (ObjectUtils.notEmpty(properties)) {
|
|
|
+ properties.forEach((key, value) -> {
|
|
|
+ this.properties.put(key, value);
|
|
|
+ this.resetLoggerLevel(key, ObjectUtils.ifNull(value, Object::toString));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
|
- public void onApplicationEvent(NacosConfigReceivedEvent event) {
|
|
|
- // 这里因Environment中的配置已被更新导致无法获取差异化配置项,故事件参数传空集合
|
|
|
- this.applicationContext.publishEvent(new EnvironmentChangeEvent(Collections.emptySet()));
|
|
|
+ public synchronized void onApplicationEvent(NacosConfigReceivedEvent event) {
|
|
|
+ // 获取差异配置
|
|
|
+ Map<String, String> different = Maps.newHashMap();
|
|
|
+ Map<String, String> config = NacosContextHolder.analyseConfig(event.getContent());
|
|
|
+ config.forEach((key, value) -> {
|
|
|
+ if (!Objects.equals(value, this.properties.get(key))) {
|
|
|
+ different.put(key, value);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.properties.forEach((key, value) -> {
|
|
|
+ String newest = config.get(key);
|
|
|
+ if (!Objects.equals(value, newest)) {
|
|
|
+ different.put(key, newest);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (ObjectUtils.notEmpty(different)) {
|
|
|
+ // 重置当前配置
|
|
|
+ this.properties.clear();
|
|
|
+ this.properties.putAll(config);
|
|
|
+
|
|
|
+ // 重置日志级别
|
|
|
+ different.forEach(this::resetLoggerLevel);
|
|
|
+
|
|
|
+ // 发布环境配置变更事件
|
|
|
+ this.applicationContext.publishEvent(new EnvironmentChangeEvent(different.keySet()));
|
|
|
+ }
|
|
|
}
|
|
|
}
|