关键词:
很久很久以前当微服务还没出现、配置中心还没出现、yaml配置文件也还没流行的时候,我们都习惯在项目里面写一个类似ResourceUtils
或者PropertiesUtil
的工具,无论在静态方法还是jsp代码都屡试不爽。如今Springcloud各种参数化配置、各种profile,Apollo、Nacos各种配置中心以及Properties、Yaml各种配置格式你的配置文件读取工具还好么?接下来我们讲解Mendmix
项目的ResourceUtils
工具类开启我们Mendmix代码解析系列课程
的篇章。
介绍
ResourceUtils贯穿了Mendmix
项目各个生命周期,在整个项目中被大量使用。目前支持Properties、Yaml配置文件解析、兼容Springcloud的profile配置方式以及无缝兼容Apollo、Nacos等各种各样的配置中心。同时还提供了诸多快速配置文件读取的方法,如:getListValue,getMapValue、getBeanValue等。
代码分析
加载过程
通过静态代码块加载本地配置文件
static
loadLocalConfigs();
loadLocalConfigs这个方法首先尝试获取spring.profiles.active
的值,为了兼容通过--spring.profiles.active=prd
的方式指定spring.profiles.active
的值,Mendmix提供了一个应用启动类基类BaseApplicationStarter
,在这个基类里面会处理各种运行参数并把设置为系统变量。
为了兼容本地运行或打包运行提供了loadPropertiesFromFile
和loadPropertiesFromJarFile
两个读取配置的方法,通过这两个方法会把本地的所有 .properties
及.yaml
文件找出来(你也拦不住两种格式的配置文件混用),并建立<文件后缀,[文件名称列表]>的映射关系如下:
".properties" : [ "/.../application-local.properties", "/.../application.properties" ]
接下来调用parseSameExtensionFiles
方法依次循环解析每个后缀名的配置文件,这个方法做了两件事情:加载所有不带profile的配置文件和找出profile的配置文件。为了确保profile的配置文件能覆盖默认配置,找出的profile的配置文件放在做好放入解析好的所有配置文件Properties里面。这样整个解析过程就完成了。
处理$引用配置
直接贴代码吧,有点长,类似方法实际上Spring提供的有,仅仅是考虑这只是一个工具类,进来少依赖,所以就自己写了。
public static String replaceRefValue(Properties properties,String value )
if(!value.contains(PLACEHOLDER_PREFIX))
return value;
String[] segments = value.split("\\\\$\\\\");
String seg;
StringBuilder finalValue = new StringBuilder();
for (int i = 0; i < segments.length; i++)
seg = StringUtils.trimToNull(segments[i]);
if(StringUtils.isBlank(seg))continue;
if(seg.contains(PLACEHOLDER_SUFFIX))
String refKey = seg.substring(0, seg.indexOf(PLACEHOLDER_SUFFIX)).trim();
//其他非$的占位符如:host
String withBraceString = null;
if(seg.contains(""))
withBraceString = seg.substring(seg.indexOf(PLACEHOLDER_SUFFIX)+1);
//如果包含默认值,如:$host:127.0.0.1
String defaultValue = null;
int defaultValSpliterIndex = refKey.indexOf(":");
if(defaultValSpliterIndex > 0)
defaultValue = refKey.substring(defaultValSpliterIndex + 1);
refKey = refKey.substring(0,defaultValSpliterIndex);
String refValue = System.getProperty(refKey);
if(StringUtils.isBlank(refValue))refValue = System.getenv(refKey);
if(StringUtils.isBlank(refValue))refValue = properties.getProperty(refKey);
if(StringUtils.isBlank(refValue))
refValue = defaultValue;
if(StringUtils.isBlank(refValue))
finalValue.append(PLACEHOLDER_PREFIX + refKey + PLACEHOLDER_SUFFIX);
else
finalValue.append(refValue);
if(withBraceString != null)
finalValue.append(withBraceString);
else
String[] segments2 = seg.split("\\\\");
if(segments2.length == 2)
finalValue.append(segments2[1]);
else
finalValue.append(seg);
整合配置中心
考虑到各种各样的配置中心,所以我们不能与具体配置中心产品绑定。所以Mendmix从Spring加载的生命周期下手。在Environment
对象加载完成后对所有配置进行一次合并,代码如下:
private static void mergeEnvironmentProperties()
MutablePropertySources propertySources = ((ConfigurableEnvironment)environment).getPropertySources();
int count;
for (PropertySource<?> source : propertySources)
if(source.getName().startsWith("servlet") || source.getName().startsWith("system"))
continue;
if(source.getName().contains("applicationConfig: [classpath"))
continue;
count = 0;
if (source instanceof EnumerablePropertySource)
for (String name : ((EnumerablePropertySource<?>) source) .getPropertyNames())
Object value = source.getProperty(name);
if(value != null)
ResourceUtils.add(name, value.toString());
count++;
System.out.println(">>merge PropertySource:" + source.getName() + ",nums:" + count);
该类在com.mendmix.spring.helper.EnvironmentHelper
,这里要注意两点:
- 确保在应用bean初始化之前完成合并
- 要跳过本地配置合并,否则可能出现远程配置又本本地配置覆盖的情况。
用法举例
假如有一份这样的配置文件
whitelist.ips=10.1.1.10;10.1.1.100
#aliyun OSS
mendmix.cos.adapter.type=aliyun
mendmix.cos.adapter.accessKey=5tHzzxhTs45tbUrKgTHYxxxx
mendmix.cos.adapter.secretKey=aIDWMP2pbvFjML7tYAzfPXXXXXXX
mendmix.cos.adapter.regionName=cn-guangzhou
#feign代理
mendmix.loadbalancer.customize.mapping[mendmix-user-svc]=http://127.0.0.1:8081
mendmix.loadbalancer.customize.mapping[mendmix-order-svc]=http://127.0.0.1:8082
部分用法
//查询指定前缀的配置
Properties properties = ResourceUtils.getAllProperties("mendmix.cos.adapter");
//查询指定前缀并返回对象
CosConfig cosConfig = ResourceUtils.getBean("mendmix.cos.adapter", CosConfig.class);
//KV格式的配置
Map<String, String> mappingValues = ResourceUtils.getMappingValues("mendmix.loadbalancer.customize.mapping");
//返回列表
List<String> whitelistIps = ResourceUtils.getList(" whitelist.ips");
// 多个配置兼容
ResourceUtils.getAnyProperty("key1","key2");
关于Mendmix
Mendmix基于Apache 2.0开源协议,100%开源。定位是一站式分布式开发架构开源解决方案及云原生架构技术底座。Mendmix提供了数据库、缓存、消息中间件、分布式定时任务、安全框架、网关以及主流产商云服务快速集成能力。基于Mendmix可以不用关注技术细节快速搭建高并发高可用基于微服务的分布式架构。
golang配置文件解析神器--viper(代码片段)
项目地址:https://github.com/spf13/viper安装方式:gogetgithub.com/spf13/viper简介viper是一个十分强大的配置文件解析工具,具有以下特点设置默认值支持的文件包括JSON,TOML,YAML,HCL,envfile和Javaproperties配置文件实时监听和重新读取配置文件从... 查看详情
webflux下整合mendmix文件上传组件上传文件到阿里云(代码片段)
...第三方云服务呢?下面以阿里云为例,我们通过Mendmix文件上传组件实现上述需求。引入依赖<dependency><groupId>com.mendmix</groupId><artifactId>mendmix-cos-adapter</artifactId><version>1.4.0</version></dependency&g... 查看详情
groovygroovy脚本调用(groovy配置文件格式|groovy配置文件读取|完整配置文件及解析代码示例)(代码片段)
...文件格式二、Groovy配置文件读取二、完整配置文件及解析代码示例前言在Groovy脚本,Groovy类,Java类中,可以调用Groovy脚本;一、Groovy配置文件格式Groovy中的配置文件,也是定义在".groovy"脚本中的;下面的写法,studentname="Tom"... 查看详情
试题解析(代码片段)
第1章基础知识及命令1.1请详细描述ins系统从打开主机电源到进入登录界面整个过程的流程。*1.开机自检(BIOS)MBR引导开机GRBU菜单加载内核INIT进程读取/etc/inittab配置文件执行/etc/rc.d/rc.sysconf执行/etc./re.d/rc.启动mingetty进入登录界... 查看详情
使用embeddedvalueresolveraware读取配置文件内容
...入这些多余的变量,有点不爽,今天研究了下,基于Spring解析@Value的方式,使用EmbeddedValueResolverAware解析配置文件,实现起来也很简单工具类如下:@ComponentpublicclassPropertiesUtilimplementsEmbed 查看详情
jeesuite-libs正式更名为:mendmix(代码片段)
关于Mendmix2015年发布第一版取名叫Jeesuite-libs一直沿用,定位是工具型软件,以各个模块能完全独立使用为前提。经过近8年的发展以及在多家大型公司技术中台、数字化转型、企业上云过程中锤炼,定制化越来越高ÿ... 查看详情
配置文件读取工具类--propertiesutil(代码片段)
/***属性工具类*@authoradmin*参考:https://www.cnblogs.com/doudouxiaoye/p/5693454.html*/publicclassPropertiesUtilprivatestaticPropertiespro=null;privatestaticMap<String,Object>map=newHashMap<String,Object>();//静态块中加载static//读取多个配置文件init("b.propert... 查看详情
13.3.2完整的mbg配置文件(mybatisgenerator逆向代码生成工具)-《ssm深入解析与项目实战》(代码片段)
13.3.2完整的MBG配置文件(MyBatisGenerator逆向代码生成工具)-《SSM深入解析与项目实战》项目中所有的源码都可以在此链接的仓库中找到:https://github.com/chenhaoxiang/uifuture-ssm文章目录13.3.2完整的MBG配置文件MBG插件位置生成代码后的文件... 查看详情
jeesuite-libs正式更名为:mendmix(代码片段)
关于Mendmix2015年发布第一版取名叫Jeesuite-libs一直沿用,定位是工具型软件,以各个模块能完全独立使用为前提。经过近8年的发展以及在多家大型公司技术中台、数字化转型、企业上云过程中锤炼,定制化越来越高ÿ... 查看详情
13.3.2完整的mbg配置文件(mybatisgenerator逆向代码生成工具)-《ssm深入解析与项目实战》(代码片段)
13.3.2完整的MBG配置文件(MyBatisGenerator逆向代码生成工具)-《SSM深入解析与项目实战》项目中所有的源码都可以在此链接的仓库中找到:https://github.com/chenhaoxiang/uifuture-ssm文章目录13.3.2完整的MBG配置文件MBG插件位置生成代码后的文件... 查看详情
ininginx配置基于文件夹的静态文档读取,使用由本地dns代理(dnsmasq)解析的私有域。(代码片段)
标注数据读取与存储案例:xml读取本地文件存储到pkl(代码片段)
...ml读取本地文件存储到pkl1.解析结构2.one_hot编码函数3.完整代码ElementTree工具使用,解析xml结构保存物体坐标结果以及类别pickle工具导出1.解析结构导入fromxml.etreeimportElementTree处理XML库importxml.etree.ElementTreeasETtree=et.parse(filen 查看详情
如何使用 JSON.net 解析 JSON 文件
...】:我正在尝试读取JSON文件并对其进行解析。我有这个代码可以从我的文件中读取StreamReaderre=newStreamReader("artists.json");JsonTextReaderreader=newJsonTextReader(re 查看详情
基于python封装读取ini文件的工具类python+requests库做接口自动化框架设计系列多测师(代码片段)
#coding=utf-8"""===========================Author:多测师_王sirTime:2020/5/2017:24Wechat:15367499889Company:上海多测师信息有限公司===========================""""""配置文件类的封装封装的目的:使用更简单封装的需求:1、简化创建配置文件解析器对象,... 查看详情
在 Webpack 中读取已解析路径的文件
】在Webpack中读取已解析路径的文件【英文标题】:ReadafileatresolvedpathinWebpack【发布时间】:2016-12-1016:42:09【问题描述】:我有一个节点模块,我想让它与webpack兼容。我目前正在使用以下模式:constfs=require(\'fs\');constsomeTemplate=requi... 查看详情
包管理工具深度解析(代码片段)
包管理工具深度解析包管理工具npm项目配置文件package.json项目配置文件package-lock.json版本管理规范npm常用命令npminstall原理(非常重要)局部命令执行方案包管理工具npm包管理工具npm:NodePackageManager,Node包管理工具... 查看详情
unity中解析excel表格工具
...自行更改路径,总之表格映射类模版文本文件位置与代码中的模版路径对应即可3——从编辑器菜单栏打开Excel工具后选择Excel文件并读取Excel文件:Excel工具—打开工具—选择Excel文件—读取Excel文件每次对Excel文件有修改... 查看详情
beegoconf文件配置解析(代码片段)
Beego默认系统配置为conf文件夹下的app.conf文件;那么app.conf里面的具体配置属性都是什么意思,接下来一一的进行解释:beege程序默认app.conf在beego程序中读取app.conf中的配置内容可以使用:beego.AppConfig.String("appname")app.conf系统配置... 查看详情