工具类ConfigTool封装Nacos Config 本地缓存(实战附代码实现)
Nacos Config的SpringBoot api使用起来不太灵活, 我们更希望要的是一个抽象的缓存工具,Nacos Config只是其中一种实现。
Nacos Config的java api并不提供本地缓存,每次请求都会去配置中心拉取数据,所以需要我们动手封装一下。
定义配置工具接口
import java.util.Map;
import java.util.Properties;public interface IConfig {String getStringConfig(String path);Object getJsonConfig(String path, String key);Map<String, Object> getJsonConfig(String path);Properties getPropertiesConfig(String path);}
Nacos Config 实现
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.qiejk.commons.util.base.JsonTool;
import com.qiejk.commons.util.base.LogTool;
import com.qiejk.commons.util.base.SpringContextTool;
import org.springframework.stereotype.Component;import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;@Component
public class NacosConfigTool implements IConfig {private static final String GROUP = "COMMON_CONFIG";private ConfigService service;// 本地缓存private Map<String, String> cache = new ConcurrentHashMap<>();private Map<String, Object> lockMap = new ConcurrentHashMap<>();public NacosConfigTool() {try {service = NacosFactory.createConfigService(SpringContextTool.getBean(ConfigConfiguration.class).getNacosServerAddr());} catch (NacosException e) {LogTool.error("NacosConfigTool init error.", e);}}private String getConfig(String dataId) {String ret;if ((ret = cache.get(dataId)) != null) {return ret;}// Nocos 的 addLisener 竟然有线程安全问题,其实是同一个节点可以add多个lisener 这里需要做一个锁定Object lock = lockMap.computeIfAbsent(dataId, k -> new Object());synchronized (lock) {if ((ret = cache.get(dataId)) == null) {ret = getConfigFromRemote(dataId);if (ret != null) {cache.put(dataId, ret);}}lockMap.remove(dataId);}return ret;}private String getConfigFromRemote(String dataId) {try {return service.getConfigAndSignListener(dataId, GROUP, 5000, new MNacosConfigListener(dataId, cache));} catch (NacosException e) {LogTool.error("NacosConfigTool getConfigFromRemote error. dataId=" + dataId, e);}return null;}// 配置监听static class MNacosConfigListener implements Listener {private String dataId;private Map<String, String> cache;public MNacosConfigListener(String dataId, Map<String, String> cache) {this.dataId = dataId;this.cache = cache;}@Overridepublic Executor getExecutor() {return null;}@Overridepublic void receiveConfigInfo(String configInfo) {cache.put(dataId, configInfo);System.out.println("MNacosConfigListener.receiveConfigInfo " + dataId + " refresh config. " + configInfo);}}@Overridepublic String getStringConfig(String dataId) {return getConfig(dataId);}@Overridepublic Object getJsonConfig(String dataId, String key) {return getJsonConfig(dataId).get(key);}@Overridepublic Map<String, Object> getJsonConfig(String dataId) {return JsonTool.json2Map(getConfig(dataId));}@Overridepublic Properties getPropertiesConfig(String dataId) {return null;}
工具类
import com.qiejk.commons.util.base.u.IConfig;import java.util.Map;
import java.util.Properties;public class ConfigTool {private static IConfig config = SpringContextTool.getBean(IConfig.class);private ConfigTool() {}public static Object getJsonConfig(String path, String key) {return config.getJsonConfig(path, key);}public static Map<String, Object> getJsonConfig(String path) {return config.getJsonConfig(path);}public static Properties getPropertiesConfig(String path) {return config.getPropertiesConfig(path);}public static String getStringConfig(String path){return config.getStringConfig(path);}}
这样我们就得到了一个不知道底层是啥实现的配置工具,并且默认实现是Nacos Config,并且默认有本地缓存。
效果
@Testpublic void testNacosConfig(){while(true){Uninterruptibles.sleepUninterruptibly(3, TimeUnit.SECONDS);System.out.println("test = " + ConfigTool.getStringConfig("test"));}}
test = 5
MNacosConfigListener.receiveConfigInfo test refresh config. 6
test = 6
test = 6
MNacosConfigListener.receiveConfigInfo test refresh config. 7
test = 7
test = 7
优化
其实还还有很大优化空间,比如本地缓存换成guava。
工具类ConfigTool封装Nacos Config 本地缓存(实战附代码实现)相关推荐
- Fresco图片加载框架的介绍,相关开源库以及工具类的封装
Fresco图片加载框架的介绍,相关开源库以及工具类的封装 本文已授权微信公众号:鸿洋(hongyangAndroid)在微信公众号平台原创首发. 简介 Fresco 是Facebook开源的安卓上的 ...
- Redis工具类的封装
Redis工具类的封装 <dependency><groupId>redis.clients</groupId><artifactId>jedis< ...
- 06篇 Nacos Client本地缓存及故障转移
学习不用那么功利,二师兄带你从更高维度轻松阅读源码- 本篇文章我们来通过源码分析一下Nacos的本地缓存及故障转移功能,涉及到核心类为ServiceInfoHolder和FailoverReactor ...
- JWT|概述|JWT结构|JWT在java中的使用|JWT工具类的封装|JWT在springboot中的使用|JWT与拦截器的配合
JWT ! 前记: 官网:https://jwt.io/ jwt有人说是用计算力换空间(相对于session) 小程序后台要求全部用springboot实现..登录状态的管理:本来想用自己随便生成UU ...
- java练习(数组工具类的封装)[目前写过最长的代码,虽然不难]
java练习(数组工具类的封装)[目前写过最长的代码,虽然不难] package myUtil.arrayUtil;public class ArraysUtil {/*** 升序排列一个byte数组 ...
- javascript 总结(常用工具类的封装)(转)
转载地址:http://dzblog.cn/article/5a6f48afad4db304be1e7a5f javascript 总结(常用工具类的封装) JavaScript 1. type 类型 ...
- javascript 总结(常用工具类的封装,转)
javascript 总结(常用工具类的封装) 前言 因为工作中经常用到这些方法,所有便把这些方法进行了总结. JavaScript 1. type 类型判断 isString (o) { //是否字 ...
- C# 网络爬虫+HtmlAgilityPack+Xpath+爬虫工具类的封装的使用
目录 1 工具准备 2 思路准备 3 附加知识准备--XPath 简述 看看例子 用XPath来寻找标签 获取所有同名的标签 获取指定标签 一个实例 最后的补充 4 代码实现 5 爬虫工具类的封装 6 ...
- ios开发循环网络请求_GitHub - JadenTeng/ResourceX: iOS网络请求,网络泛型编程,工具类的封装,基于AFNetworking 实现, NSCache数据缓存...
ResourceX 通过AFNetworking.YYModel 解析网络泛型编程简化网络请求 现如今,网络通信几乎涉及每一个app程序.对于绝大多数请求HTTP API的方法,它们的执行流程都可以分 ...
- Redis存储缓存工具类简单封装
一.公共实体类 (1)User.java package cn.xiyou.entity;import java.io.Serializable;/*** User实体* * @author XIOA ...
最新文章
- 【Linux探索之旅】第二部分第五课:用户和权限,有权就任性
- JAVA自带监控工具的介绍
- php编程对联,形容程序员的对联大全
- 初始ES6-Webpack
- 转录组分析_转录组+?分析+?实验=2区文章
- treelist 判断父子节点_DOM(4)-节点
- dubbo 学习笔记 -- provider端
- 我的2015plan
- OpenGL笔记5 shader 调试信息获取 Debug
- ios整理(五)小应用-重力感应
- ASP.NET Core使用Session
- 调试 STM32F429 + USB3300
- gitlab取消邮箱验证(适用gitlab各个版本)
- 困扰我两天的问题(nginx配置好ssl证书,https却不能访问)
- Guass列主元、平方根法、追赶法求解方程组的C++实现
- 新换的手机号码被人注册了微信怎么办?
- C语言求矩阵的逆(高斯法)
- android手机设置固定dns,手机dns怎么设置 简单几步就搞定
- 【经验】VMware|windows更新20H2版本后VMware虚拟机无法开启(禁用Device guard)
- java-网页404(个例)
热门文章
- 形式语言与自动机 第三章 课后题答案
- c语言超市,C语言超市收银系统
- 触摸按键 原理 研究笔记
- java 抽象类命名_Java命名规范
- 欢度国庆⭐️共享爬虫之美⭐️基于 Python 实现微信公众号爬虫(Python无所不能爬)
- Spring Cloud Alibaba 基础教程:支持的几种服务消费方式(RestTemplate、WebClient、Feign)
- kdj买卖指标公式源码_买卖点KDJ版指标详解 通达信通达信KDJ
- iOS实现模拟定位功能
- windows磁盘空间释放(二)
- CSP202006-1 线性分类器(100分)【数学】