package com.config.center;
import com.alibaba.fastjson.JSON;
import com.config.center.model.*;
import com.config.center.utils.DataTransUtil;
import com.config.center.utils.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author caojiancheng
* @date 2024-02-20 18:21
*/
@Slf4j
public class ConfigCenterClient {
/**
* 服务端地址
*/
private String url;
//配置map
private Map<Long, ConfigBO> configMap;
private static volatile ConfigCenterClient client;
private List<Object> refreshBeanList;
private List<RefreshFieldValueBO> refreshFieldValueList;
public static final String PROPERTY_SOURCE_NAME = "configCenter";
private ConfigCenterClient(String url) {
this.url = url;
this.refreshBeanList = new ArrayList<>();
this.refreshFieldValueList = new ArrayList<>();
//将配置中心的配置转换成property格式,即user.name=xxx
List<ConfigVO> configList = getAllValidConfig();
this.configMap = configList2ConfigMap(configList);
}
public static ConfigCenterClient getInstance(String url) {
return Optional.ofNullable(client).orElseGet(() -> {
synchronized (ConfigCenterClient.class) {
if (client == null) {
client = new ConfigCenterClient(url);
}
return client;
}
});
}
public List<ConfigVO> getAllValidConfig() {
HttpRespBO httpRespBO = HttpUtil.httpGet(url + "/config/get");
return httpResp2ConfigVOList(httpRespBO);
}
public void addRefreshField(String key, RefreshFieldBO refreshFieldBO) {
configMap.values().stream().map(ConfigBO::getConfigDataList).filter(Objects::nonNull)
.flatMap(List::stream).filter(configDataBO -> configDataBO.getKey().equals(key))
.findFirst().ifPresent(configDataBO -> configDataBO.addRefreshField(refreshFieldBO));
}
public void addRefreshFieldValue(Object bean, Field field, String value) {
refreshFieldValueList.add(new RefreshFieldValueBO(bean, field, value));
}
public void addRefreshBeanList(Object bean) {
refreshBeanList.add(bean);
}
public Map<String, Object> getConfigProperty() {
return configMap.values().stream().map(ConfigBO::getConfigDataList).filter(Objects::nonNull)
.flatMap(List::stream).collect(Collectors.toMap(ConfigDataBO::getKey, ConfigDataBO::getValue, (k1, k2) -> k1));
}
public void startShortPolling() {
polling("/config/change/get", () -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, 2000);
}
public void startLongPolling() {
polling("/config/change/get/long", null, 30000);
}
public void polling(String uri, Runnable runnable, int readTimeout) {
Thread thread = new Thread(() -> {
while (!Thread.interrupted()) {
try {
Optional.ofNullable(runnable).ifPresent(Runnable::run);
Map<Long, List<ConfigDataBO>> refreshConfigMap = new HashMap<>();
configMap.values().forEach(configBO -> {
Optional.ofNullable(configBO.getConfigDataList()).ifPresent(cdList -> cdList.stream()
.filter(cd -> cd.getRefreshFieldList() != null && !cd.getRefreshFieldList().isEmpty())
.forEach(refreshConfigMap.computeIfAbsent(configBO.getId(), k1 -> new ArrayList<>())::add));
});
if (refreshConfigMap.isEmpty()) {
return;
}
Map<String, Integer> configIdMap = refreshConfigMap.keySet().stream()
.collect(Collectors.toMap(String::valueOf, configId -> configMap.get(configId).getVersion()));
HttpRespBO httpRespBO = HttpUtil.httpPostJson(url + uri, JSON.toJSONString(configIdMap), readTimeout);
List<ConfigVO> configList = httpResp2ConfigVOList(httpRespBO);
if (configList.isEmpty()) {
continue;
}
configList.forEach(configVO -> {
Map<String, Object> result = new HashMap<>();
DataTransUtil.buildFlattenedMap(result, configVO.getConfigData(), "");
ConfigBO configBO = this.configMap.get(configVO.getId());
configBO.setVersion(configVO.getVersion());
List<ConfigDataBO> configDataList = configBO.getConfigDataList();
Map<String, ConfigDataBO> configDataMap = configDataList.stream()
.collect(Collectors.toMap(ConfigDataBO::getKey, Function.identity()));
result.forEach((key, value) -> {
ConfigDataBO configDataBO = configDataMap.get(key);
if (configDataBO == null) {
configDataList.add(new ConfigDataBO(key, value.toString()));
} else {
configDataBO.setValue(value.toString());
List<RefreshFieldBO> refreshFieldList = configDataBO.getRefreshFieldList();
if (refreshFieldList == null) {
refreshFieldList = new ArrayList<>();
configDataBO.setRefreshFieldList(refreshFieldList);
}
refreshFieldList.forEach(refreshFieldBO -> {
try {
Field field = refreshFieldBO.getField();
field.setAccessible(true);
field.set(refreshFieldBO.getBean(), value.toString());
} catch (Exception e) {
log.error("startShortPolling set Field error", e);
}
});
}
});
});
} catch (Exception e) {
log.error("startShortPolling error", e);
}
}
});
thread.setName("startShortPolling");
thread.setDaemon(true);
thread.start();
}
public void startSpringBootLongPolling(ConfigurableEnvironment environment, ConfigurableBeanFactory beanFactory) {
if (configMap.isEmpty() || refreshFieldValueList.isEmpty()) {
log.info("configMap.size:{} refreshFieldValueList.size:{}", configMap.size(), refreshFieldValueList.size());
return;
}
MutablePropertySources propertySources = environment.getPropertySources();
MapPropertySource configCenter = (MapPropertySource) propertySources.get(PROPERTY_SOURCE_NAME);
if (configCenter
没有合适的资源?快使用搜索试试~ 我知道了~
config-center
共52个文件
java:37个
gradle:6个
yml:2个
需积分: 0 0 下载量 138 浏览量
2024-05-16
15:12:01
上传
评论 1
收藏 100KB ZIP 举报
温馨提示
config-center
资源推荐
资源详情
资源评论
收起资源包目录
config-center-master.zip (52个子文件)
config-center-master
gradle
wrapper
gradle-wrapper.jar 58KB
gradle-wrapper.properties 199B
gradlew.bat 3KB
client
src
test
resources
spring
applicationContext.xml 468B
application.yml 48B
java
com
config
center
test
ClientTest.java 2KB
ConfigApplication.java 489B
User.java 297B
main
resources
META-INF
spring.factories 230B
java
com
config
center
autoconfigure
ConfigAutoConfiguration.java 640B
annotation
ConfigRefresh.java 260B
ConfigCenterClient.java 13KB
utils
HttpUtil.java 5KB
DataTransUtil.java 2KB
model
ConfigDataBO.java 749B
ConfigBO.java 406B
RefreshFieldValueBO.java 471B
RefreshFieldBO.java 407B
HttpRespBO.java 1KB
HttpReqBO.java 805B
test
ConfigTest2.java 892B
ConfigTest.java 389B
config
ConfigRefreshAnnotationBeanPostProcessor.java 4KB
ConfigEnvironmentPostProcessor.java 1KB
build.gradle 675B
build.gradle 409B
settings.gradle 87B
gradlew 6KB
common
src
main
java
com
config
center
enums
ResultEnum.java 298B
model
ConfigVO.java 502B
Result.java 2KB
build.gradle 206B
model
build.gradle 26B
.gitignore 69B
server
src
main
resources
application.yml 220B
java
com
config
center
controller
ConfigController.java 4KB
utils
DateUtil.java 517B
dao
ConfigDAO.java 988B
impl
LocalConfigDAO.java 4KB
service
ConfigService.java 1KB
impl
ConfigServiceImpl.java 8KB
LocalConfigSyncServiceImpl.java 653B
ConfigSyncService.java 351B
enums
ConfigCenterModeEnum.java 560B
WhetherEnum.java 805B
ConfigCenterApplication.java 390B
model
ConfigBO.java 543B
ConfigPolingTasksHolder.java 1KB
ConfigPolingTask.java 467B
ConfigDO.java 473B
BaseDO.java 585B
build.gradle 416B
共 52 条
- 1
资源评论
m0_46375122
- 粉丝: 0
- 资源: 29
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 单家独院式农房户型设计水电图.dwg
- STC12C5A60S2单片机+LCD12864俄罗斯方块源码程序实例源码KEIL C51工程文件.zip
- 编程IDE等宽字体,不错的
- FlowGeek FlowGeek是基于MVP架构的、遵循Material Design设计规范的开源中国社区客户端
- 单家独院式图纸农房户型设计90平09.20-t3.dwg
- 使用HttpURLConnect实现的文件下载器
- STM32驱动OLED1.54寸OLED驱动代码
- STC12C5A60S2单片机开发LCD12864液晶显示正弦函数实例源码KEIL C51工程文件.zip
- SI9933BDY-T1-E3-VB一款SOP8封装2个P-Channel场效应MOS管
- C++开发基于ROS实现多差速无人车编队控制源码+使用说明+详细注释 (期末大作业)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功