一、功能描述
基于nacos管理配置服务,这里借助starter机制与nacos,mysql一起配合管理非核心业务的配置类数据记录,基于json存储,简化业务配置类数据的管理。
二、实现原理
通过自定义注解将实体数据与nacos配置数据进行绑定动态与nacos进行交互,并解析数据,通过接口访问。
2.1 配置说明
nacos:
papertext:
dataIDArr: com.coderman.common.starter.papertext
groupIDArr: 0-SMS_ORDER_GROUP,0-SMS_COUPON_GROUP
这里采用的配置格式与之前的工具组件一样,不再叙述。
2.2 代码实现
- 定义配置数据类
@Configuration
@ConfigurationProperties(prefix = "nacos.papertext")
public class NacosPaperTextProperties {
/**
* nacos的dataID
*
*/
private String [] dataIDArr;
/**
* nacos的groupId
* 与dataID进行映射时采用
* 0:groupId0,
* 1:groupId1格式,0,1则是nacos dataID 在dataIDArr
* 的索引位置
*/
private String [] groupIDArr;
public String[] getDataIDArr() {
return dataIDArr;
}
public void setDataIDArr(String[] dataIDArr) {
this.dataIDArr = dataIDArr;
}
public String[] getGroupIDArr() {
return groupIDArr;
}
public void setGroupIDArr(String[] groupIDArr) {
this.groupIDArr = groupIDArr;
}
@Override
public String toString() {
return "NacosDataConfig{" +
"dataIDArr=" + Arrays.toString(dataIDArr) +
", groupIDArr=" + Arrays.toString(groupIDArr) +
'}';
}
}
- 服务包装类
@Service
public class PaperWorkConfigWrapper {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
private ConfigService configService;
/**
* 包装configservice
* @return
* @throws NacosException
*/
public synchronized ConfigService getConfigService() throws NacosException {
if(configService == null){
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, nacosDiscoveryProperties.getServerAddr());
configService = NacosFactory.createConfigService(properties);
}
return configService;
}
}
- 定义监听器SpringPaperTextConfigListener
@Order(value = 1001)
@Component
public class SpringPaperTextConfigListener implements ApplicationListener<ApplicationStartedEvent> {
private Logger logger = LoggerFactory.getLogger(SpringPaperTextConfigListener.class);
@Autowired
private NacosPaperTextProperties nacosDataProperties;
@Autowired
private NacosConfigListener configListener;
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
try {
logger.info("应用启动成功,准备初始化业务配置数据:PaperTextConfig.......................");
configListener.addListener(nacosDataProperties.getDataIDArr(),nacosDataProperties.getGroupIDArr());
logger.info("应用启动成功,初始化业务配置数据成功:PaperTextConfig.......................");
} catch (Exception e) {
logger.error("初始化远程配置失败:PaperTextConfig",e);
}
}
}
- 定义配置变更监听接口
public interface IListener {
/**
* 对配置的nacos dataID-group进行
* 注册变更监听
*/
void addListener(String [] dataIdArr, String [] groupIdArr) throws NacosException;
}
- 定义配置变更监听实现
@Service
public class NacosConfigListener implements IListener{
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
@Autowired
private ConfigDataHelperService configDataHelperService;
@Autowired
private PaperWorkConfigWrapper paperWorkConfigWrapper;
@Override
public void addListener(String [] dataIDArr, String [] groupIDArr) throws NacosException {
Map<String,String> dataIDMap = new HashMap<>();
if(dataIDArr != null && dataIDArr.length > 0){
for (int i = 0;i < dataIDArr.length; i++){
dataIDMap.put(i+"", dataIDArr[i]);
}
}
if(groupIDArr == null || groupIDArr.length == 0){
logger.error("nacos data not fund groupIdArr ,please check your config application-nacosdatadict.yml");
return;
}
ConfigService configService = paperWorkConfigWrapper.getConfigService();
for (String str : groupIDArr){
String [] strArr = str.split("-");
String dataID = dataIDMap.get(strArr[0]);
String groupId = strArr[1];
if(StringUtils.isNotEmpty(dataID)){
String content = configService.getConfig(dataID, groupId, 3000);
configDataHelperService.addConfig(dataID,groupId,content);
addListener(dataID,groupId);
}
}
}
/**
* 针对不同的dataid,groupid添加listener
* @param dataId
* @param groupID
* @throws NacosException
*/
private void addListener(String dataId, final String groupID) throws NacosException {
ConfigService configService = paperWorkConfigWrapper.getConfigService();
configService.addListener(dataId, groupID, new Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
logger.info("dataId={},groupId={} has new data changed.",dataId,groupID);
configDataHelperService.addConfig(dataId,groupID,configInfo);
}
@Override
public Executor getExecutor() {
return null;
}
});
}
}
- 定义文案配置获取接口
public interface PaperTextService {
/**
* 根据dataid,groupid,varmap获取转换后的文案数据
* @param dataId
* @param groupId
* @param varMap
* @return
*/
String getMsgFromTemplate(String dataId, String groupId, Map<String,String> varMap);
}
- 定义文案配置获取实现
@Service
public class NacosPaperTextServiceImpl implements PaperTextService{
@Autowired
private ConfigDataHelperService configDataHelperService;
@Override
public String getMsgFromTemplate(String dataId, String groupId, Map<String, String> varMap) {
return configDataHelperService.getNewConfig(dataId, groupId, varMap);
}
}
- 定义辅助服务类
@Service
public class ConfigDataHelperService {
private static ConcurrentHashMap<String,String> concurrentHashMap = new ConcurrentHashMap<>();
/**
* 将数据存入map容器中
* @param dataId
* @param groupId
* @param content
*/
public void addConfig(String dataId,String groupId,String content){
String key = dataId+"-"+groupId;
concurrentHashMap.put(key,content);
}
/**
* 根据dataId 和 groupId获取配置内容
* @param dataId
* @param groupId
* @return
*/
private String getConfig(String dataId,String groupId){
String key = dataId+"-"+groupId;
return concurrentHashMap.get(key);
}
/**
*
* @param dataId
* @param groupId
* @param varMap
* @return
*/
public String getNewConfig(String dataId, String groupId, Map<String,String> varMap){
String contentTemplate = getConfig(dataId,groupId);
return getNewConfig(contentTemplate,varMap);
}
/**
* 进行文本占位符替换
* @param template
* @param varMap
* @return
*/
private String getNewConfig(String template ,Map<String,String> varMap ){
String temp = template;
if(varMap == null || varMap.isEmpty()){
return template;
}
for (Map.Entry<String,String> entry : varMap.entrySet()){
String key = "\\$\\{"+entry.getKey()+"\\}";
temp = temp.replaceAll(key,entry.getValue());
}
return temp;
}
}
我最近整了一个公众号,持续输出原创内容,敬请关注: