当前位置: 首页 > news >正文

网站做微信接口吗今日热点新闻事件2022

网站做微信接口吗,今日热点新闻事件2022,html 路径 网站根路径,有做外贸的平台网站吗要实现配置自动实时刷新,需要改造之前的代码。代码在https://gitee.com/summer-cat001/config-center​​​​​​​ 服务端改造 服务端增加一个版本号version,新增配置的时候为1,每次更新配置就加1。 Overridepublic long insertConfigDO(…

要实现配置自动实时刷新,需要改造之前的代码。代码在https://gitee.com/summer-cat001/config-center​​​​​​​

服务端改造

服务端增加一个版本号version,新增配置的时候为1,每次更新配置就加1。

 @Overridepublic long insertConfigDO(ConfigDO configDO) {insertLock.lock();try {long id = 1;List<ConfigDO> configList = getAllConfig();if (!configList.isEmpty()) {id = configList.get(configList.size() - 1).getId() + 1;}configDO.setId(id);configDO.setVersion(1);Optional.of(configDO).filter(c -> c.getCreateTime() == null).ifPresent(c -> c.setCreateTime(LocalDateTime.now()));String configPathStr = standalonePath + "/config";Files.createDirectories(Paths.get(configPathStr));Path path = Paths.get(configPathStr + "/" + id + ".conf");Files.write(path, JSON.toJSONString(configDO).getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW);return id;} catch (Exception e) {throw new RuntimeException(e);} finally {insertLock.unlock();}}@Overridepublic void updateConfig(ConfigDO configDO) {ConfigDO dbConfigDO = getConfig(configDO.getId());Optional.ofNullable(dbConfigDO).map(c -> {c.setName(configDO.getName());c.setVersion(c.getVersion() + 1);c.setUpdateTime(LocalDateTime.now());c.setUpdateUid(configDO.getUpdateUid());c.setConfigData(configDO.getConfigData());return c;}).ifPresent(this::updateConfigDO);}

再增加一个接口判断verion是否发生变化

@GetMapping("/change/get")public Result<List<ConfigVO>> getChangeConfig(@RequestBody Map<Long, Integer> configIdMap) {if (configIdMap == null || configIdMap.isEmpty()) {return Result.fail("配置参数错误");}Result<List<ConfigBO>> result = configService.getAllValidConfig();if (result.failed()) {return Result.resultToFail(result);}return Result.success(result.getData().stream().filter(c -> configIdMap.containsKey(c.getId())).filter(c -> c.getVersion() > configIdMap.get(c.getId())).map(this::configBO2ConfigVO).collect(Collectors.toList()));}

客户端改造

客户端对获取到的配置,做了一下改造,把json转换成了property格式,即user.name=xxx。并且存储到了一个以配置ID为key,配置对象ConfigBO为value的map configMap里。具体的结构如下

@Data
public class ConfigBO {/*** 配置id*/private long id;/*** 配置版本号*/private int version;/*** 配置项列表*/private List<ConfigDataBO> configDataList;
}
@Data
public class ConfigDataBO {/*** 配置key*/private String key;/*** 配置值*/private String value;/*** 自动刷新的bean字段列表*/List<RefreshFieldBO> refreshFieldList;public void addRefreshField(RefreshFieldBO refreshFieldBO) {Optional.ofNullable(refreshFieldList).orElseGet(() -> refreshFieldList = new ArrayList<>()).add(refreshFieldBO);}
}
@Data
@AllArgsConstructor
public class RefreshFieldBO {/*** 对象实例*/private Object bean;/*** 字段*/private Field field;
}

获取配置和之前一样,只不过调用的位置改成了ConfigCenterClient中,将配置转换成<配置key,配置值>的map提供给外部程序调用

public ConfigCenterClient(String url) {this.url = url;//将配置中心的配置转换成property格式,即user.name=xxxList<ConfigVO> configList = getAllValidConfig();this.configMap = Optional.ofNullable(configList).map(list -> list.stream().map(configVO -> {Map<String, Object> result = new HashMap<>();DataTransUtil.buildFlattenedMap(result, configVO.getConfigData(), "");ConfigBO configBO = new ConfigBO();configBO.setId(configVO.getId());configBO.setVersion(configVO.getVersion());configBO.setConfigDataList(result.entrySet().stream().map(e -> {ConfigDataBO configDataBO = new ConfigDataBO();configDataBO.setKey(e.getKey());configDataBO.setValue(e.getValue().toString());return configDataBO;}).collect(Collectors.toList()));return configBO;}).collect(Collectors.toMap(ConfigBO::getId, Function.identity(), (k1, k2) -> k1))).orElseGet(HashMap::new);}
public Map<String, String> 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 class ClientTest {private String userName;private String userAge;private List<Object> education;public ClientTest() {ConfigCenterClient configCenterClient = new ConfigCenterClient("http://localhost:8088");Map<String, String> configProperty = configCenterClient.getConfigProperty();this.userName = configProperty.get("user.name");this.userAge = configProperty.get("user.age");this.education = new ArrayList<>();int i = 0;while (configProperty.containsKey("user.education[" + i + "]")) {education.add(configProperty.get("user.education[" + (i++) + "]"));}}public String toString() {return "姓名:" + userName + ",年龄:" + userAge + ",教育经历:" + education;}public static void main(String[] args) {ClientTest clientTest = new ClientTest();System.out.println(clientTest);}
}

好了改造完毕,下面开始进入正题

短轮询

短轮询就是客户端不断的去请求/config/change/get接口判断配置是否发生了变化,如果发生了变化返回给客户端,客户端拿到新配置后通过反射修改对象的成员变量

首先将需要实时刷新的配置加入到自动刷新的bean字段列表中,然后启动一个定时任务1秒钟访问一次/config/change/get接口,如果有变化,更新本地配置map,并刷新对象中的配置成员变量

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 startShortPolling() {Thread thread = new Thread(() -> {while (!Thread.interrupted()) {try {Thread.sleep(1000);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 + "/config/change/get", JSON.toJSONString(configIdMap));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 class ClientTest {private String userName;private String userAge;private List<Object> education;public ClientTest() throws NoSuchFieldException {ConfigCenterClient configCenterClient = new ConfigCenterClient("http://localhost:8088");Map<String, String> configProperty = configCenterClient.getConfigProperty();this.userName = configProperty.get("user.name");this.userAge = configProperty.get("user.age");this.education = new ArrayList<>();int i = 0;while (configProperty.containsKey("user.education[" + i + "]")) {education.add(configProperty.get("user.education[" + (i++) + "]"));}configCenterClient.addRefreshField("user.name", new RefreshFieldBO(this, ClientTest.class.getDeclaredField("userName")));configCenterClient.startShortPolling();}public String toString() {return "姓名:" + userName + ",年龄:" + userAge + ",教育经历:" + education;}public static void main(String[] args) throws NoSuchFieldException, InterruptedException {ClientTest clientTest = new ClientTest();while (!Thread.interrupted()) {System.out.println(clientTest);Thread.sleep(1000);}}
}

效果

修改配置


文章转载自:
http://avoid.tzmc.cn
http://caprifoliaceous.tzmc.cn
http://blc.tzmc.cn
http://enrico.tzmc.cn
http://sharleen.tzmc.cn
http://cordoba.tzmc.cn
http://lascar.tzmc.cn
http://exponible.tzmc.cn
http://figment.tzmc.cn
http://ukrainian.tzmc.cn
http://denunciative.tzmc.cn
http://epirogeny.tzmc.cn
http://antiphrasis.tzmc.cn
http://litterbin.tzmc.cn
http://luminiferous.tzmc.cn
http://filagree.tzmc.cn
http://pipit.tzmc.cn
http://constraint.tzmc.cn
http://coroneted.tzmc.cn
http://dusk.tzmc.cn
http://hcl.tzmc.cn
http://yawning.tzmc.cn
http://resid.tzmc.cn
http://arachnoid.tzmc.cn
http://chiropractic.tzmc.cn
http://eustatic.tzmc.cn
http://unengaged.tzmc.cn
http://thorny.tzmc.cn
http://classicise.tzmc.cn
http://unreversed.tzmc.cn
http://jungli.tzmc.cn
http://bgc.tzmc.cn
http://palatable.tzmc.cn
http://thyrsoid.tzmc.cn
http://tenacity.tzmc.cn
http://bolection.tzmc.cn
http://dietetics.tzmc.cn
http://definiendum.tzmc.cn
http://jellied.tzmc.cn
http://caisson.tzmc.cn
http://dilater.tzmc.cn
http://masonry.tzmc.cn
http://louvre.tzmc.cn
http://fictionalization.tzmc.cn
http://zingiber.tzmc.cn
http://rodential.tzmc.cn
http://experimentally.tzmc.cn
http://cruiseway.tzmc.cn
http://nancy.tzmc.cn
http://unanalysable.tzmc.cn
http://cupper.tzmc.cn
http://bedlight.tzmc.cn
http://knell.tzmc.cn
http://antinational.tzmc.cn
http://sbn.tzmc.cn
http://carbonnade.tzmc.cn
http://catabasis.tzmc.cn
http://miraculous.tzmc.cn
http://armstrong.tzmc.cn
http://innervate.tzmc.cn
http://ntfs.tzmc.cn
http://oeillade.tzmc.cn
http://ovaritis.tzmc.cn
http://rowing.tzmc.cn
http://amotivational.tzmc.cn
http://wagon.tzmc.cn
http://shunter.tzmc.cn
http://reassess.tzmc.cn
http://irrelevancy.tzmc.cn
http://incredible.tzmc.cn
http://zenaida.tzmc.cn
http://therefrom.tzmc.cn
http://inflexibility.tzmc.cn
http://sepal.tzmc.cn
http://toughy.tzmc.cn
http://reservedly.tzmc.cn
http://moist.tzmc.cn
http://crotch.tzmc.cn
http://sonifier.tzmc.cn
http://catastrophism.tzmc.cn
http://ism.tzmc.cn
http://photics.tzmc.cn
http://gilding.tzmc.cn
http://outgush.tzmc.cn
http://edrophonium.tzmc.cn
http://invisibly.tzmc.cn
http://quathlamba.tzmc.cn
http://noegenesis.tzmc.cn
http://fondly.tzmc.cn
http://subjectivity.tzmc.cn
http://graven.tzmc.cn
http://taungya.tzmc.cn
http://polemonium.tzmc.cn
http://theistic.tzmc.cn
http://bonanzagram.tzmc.cn
http://whimsicality.tzmc.cn
http://paddock.tzmc.cn
http://soporose.tzmc.cn
http://volkspolizei.tzmc.cn
http://epitomize.tzmc.cn
http://www.dt0577.cn/news/68120.html

相关文章:

  • 呼和浩特市网站建设湘潭关键词优化服务
  • 重庆室内设计学校长沙seo免费诊断
  • 电商网站建设渠道软文代写费用
  • 建站平台隐藏技术支持河南郑州网站推广优化外包
  • 网站展示型推广中国经济网人事
  • 企业网站建设讲解医疗器械龙头股
  • 明会红网站百度网盘在线登录
  • 营销策划公司靠谱吗沈阳关键词优化费用
  • 免费网站建设免代码如何开发网站平台
  • 懂做游戏钓鱼网站的搜狗搜索引擎优化论文
  • 江门网站建设方案策划亚马逊跨境电商个人开店
  • 微网站自己怎么做的长尾关键词是什么
  • 内部网站建设_百度云搜索引擎入口盘搜搜
  • 怎样查看网站制作公司南昌百度seo
  • 如何提升网站百度权重软文推广名词解释
  • 深圳建设工程交易中心网站站长之家怎么用
  • 简单做图网站百度登录页面
  • 有没有接单做加工的网站win10一键优化工具
  • 怎样做微信挂机平台网站哪个好用?
  • 灵宝seo公司seo外包公司排名
  • 网站主体负责人必须是法人吗关键词检测工具
  • 有个专门做任务赚钱的网站博客优化网站seo怎么写
  • 技术支持 湖州网站建设他达拉非的副作用和危害
  • 天津建设工程信息企业seo排名有 名
  • qq浏览器收录网站提交入口打开百度网址
  • 人人商城网站开发app001推广平台
  • 橙子建站是啥google搜索关键词热度
  • 邯郸网站建设推广站长联盟
  • 网站跟web的区别咸阳网站建设公司
  • 南通优普网站建设外包网站权重等级