前言

在前两次的 cicada 版本中其实还不支持读取配置文件,比如对端口、路由的配置。

因此我按照自己的想法创建了一个 issue ,也收集到了一些很不错的建议。

最终其实还是按照我之前的想法来做了这个配置管理。

同时将 cicada 升级到了 v1.0.2

目标

在做之前是要把需求想好,到底怎样的一个配置管理是对开发人员来说比较友好的?

我认为有以下几点:

  • 可以自定义配置,并且支持不同的环境(开发、测试、生产)。
  • 使用灵活。对使用者来说不要有太多的束缚。

理论上来说配置这个东西应当完全独立出来,由一个配置中心来负责管理并且这样可以与应用解耦。

不过这样的实现和当前 cicada 的定义有些冲突,我想尽量小的依赖第三方组件并可以完全独立运行。

因此基于这样的情况便有了以下的实现。

使用

在看实现之前先看看基于目前的配置管理如何在业务中使用起来。

结合现在大家使用 SpringBoot 的习惯,cicada 默认会读取 classpath 下的 application.properties 配置文件。并且会默认读取其中的应用端口以及初始路由地址。

同时也新增了一个 api。

public class MainStart {

    public static void main(String[] args) throws Exception {
CicadaServer.start(MainStart.class,"/cicada-example") ;
}
} public class MainStart { public static void main(String[] args) throws Exception {
CicadaServer.start(MainStart.class) ;
}
}

这样在不传默认地址的时候 cicada 会从 application.properties 中读取。

考虑到后面可维护的情况,cicada 也支持配置各种不同的配置文件。

使用也比较简单,只需要继承 cicada 提供的一个抽象类即可。

public class KafkaConfiguration extends AbstractCicadaConfiguration {

    public KafkaConfiguration() {
super.setPropertiesName("kafka.properties");
} } public class RedisConfiguration extends AbstractCicadaConfiguration { public RedisConfiguration() {
super.setPropertiesName("redis.properties");
} }

按照这样的配置也会默认从 classpath 读取这两个配置文件。

当然这里有个前提:代码里配置的文件名必须得和配置文件名称相同。

那如何在业务中读取这两个配置文件的内容呢?

这也简单,代码一看就懂:

  • 首先需要通过 ConfigurationHolder 获取各自不同配置的管理对象(需要显式指定类类型)。
  • 通过 get() 方法直接获取配置。
  • 同时也支持获取 application.properties 里的配置。

同时为了支持在不同环境的使用,当配置了启动参数将会优先读取。

-Dapplication.properties=/xx/application.properties
-Dkafka.properties=/xx/kakfa.properties
-Dredis.properties=/xx/redis.properties

这样算是基本实现了上述的配置要求。

实现

要实现以上的功能有几个核心点:

  1. 加载所有配置文件。
  2. 将不同的配置文件用不同的对象进行管理。
  3. 提供简易的接口使用。

由于 cicada 需要支持多个配置文件,所有需要定义一个抽象类供所有的配置管理实现。

定义比较简单,其中有两个重要的成员变量:

  • 文件名称:用于初始化时通过名称加载配置文件。
  • Properties 其实就是一个 Map 结构的缓存,用于存放所有的配置。当然对外提供的查询是基于它的。

接着就是在初始化时需要找出所有继承了 AbstractCicadaConfiguration 的类。

查询出来之后自然是要进行遍历同时反射创建对象。

由于之前已经调用了

super.setPropertiesName("redis.properties");

来赋值配置文件名称,所以还需要在遍历过程中将 Properties 进行赋值。

同时在这里也体现出优先读取的是 VM 启动参数中的配置文件。

String systemProperty = System.getProperty(conf.getPropertiesName());

需要额外提一点的是:在查找所有用户自定义的配置管理类时需要手动将 cicada 内置的

ApplicationConfiguration 加入其中。

因为使用应用的包名通过反射是查询不出该类的。

保存自定义配置管理

为了方便用户在使用时候可以随意的读取各个配置文件,所以还需要将反射创建的对象保存到一个内部缓存中,核心代码就是上上图中的这段代码:

// add configuration cache
ConfigurationHolder.addConfiguration(aClass.getName(), conf);

其中 ConfigurationHolder 的定义如下。

其实也是利用一个 Map 来存放这些对象。

这样在使用时候只需要取出即可。

KafkaConfiguration configuration = (KafkaConfiguration) getConfiguration(KafkaConfiguration.class);
String brokerList = configuration.get("kafka.broker.list");

重构

本次升级同时还重构了部分代码,比如启动类。

现在看上去要清爽和直接的多:

其中也有一点需要注意的地方。

大家如果查看日志的话会发现应用启动之后会打印本次的耗时,自然就是在启动时候记录一个时间,初始化完毕之后记录一个即可。

在之前的实现中由于都是在一个方法内,所以直接使用就行了。

但现在优化之后跨越了不同的方法和类,难道要把时间作为参数在各个方法之前传递嘛?

那未免太不优雅了。

所以 ThreadLocal 就有了发挥余地。

在初始化的方法中我将当前时间写入:

ThreadLocalHolder.setLocalTime(System.currentTimeMillis());

在最后记录日志的地方直接取出比较即可:

这样使用起来就完全不需要管什么参数传递了。

同时 ThreadLocalHolder 的定义:

这里还是有一点需要注意,在这种长生命周期的容器中一定得要记得及时清除

我这里的时间在查询一次之后就不用了,所以完全放心的在 getLocalTime() 方法中删掉。

总结

这就是本次 v1.0.2 中的升级内容,包含了配置支持以及代码重构。其中有些内容我觉得对接触少的同学来说还是挺有帮助的。

关于上两次的版本介绍请查看这里:

还没点关注的朋友可以点波关注:

https://github.com/TogetherOS/cicada

也欢迎大家参与一起维护!。

同时后续关于 cicada 的更新会放慢一些。会介绍一些平时实战相关的内容,比如 Kafka 之类的,请持续关注。

你的点赞与转发是最大的支持。

「造个轮子」——cicada 设计一个配置模块的更多相关文章

  1. 「造个轮子」——cicada 源码分析

    前言 两天前写了文章<「造个轮子」--cicada(轻量级 WEB 框架)> 向大家介绍了 cicada 之后收到很多反馈,也有许多不错的建议. 同时在 GitHub 也收获了 80 几颗 ...

  2. 「造个轮子」——cicada(轻量级 WEB 框架)

    前言 俗话说 「不要重复造轮子」,关于是否有必要不再本次讨论范围. 创建这个项目的主要目的还是提升自己,看看和知名类开源项目的差距以及学习优秀的开源方式. 好了,现在着重来谈谈 cicada 这个项目 ...

  3. 「造个轮子」——设计 HTTP 请求全局上下文

    前言 本次 Cicada 已经更新到了 v1.0.3. 主要是解决了两个 issue,#9(Boss线程数好像设置有误 ) #8(怎么返回纯字符串内容不要JSON格式?). 所以本次的主要更新为: C ...

  4. 「Netty实战 02」手把手教你实现自己的第一个 Netty 应用!新手也能搞懂!

    大家好,我是 「后端技术进阶」 作者,一个热爱技术的少年. 很多小伙伴搞不清楚为啥要学习 Netty ,今天这篇文章开始之前,简单说一下自己的看法: @ 目录 服务端 创建服务端 自定义服务端 Cha ...

  5. 【LOJ】#3036. 「JOISC 2019 Day3」指定城市

    LOJ#3036. 「JOISC 2019 Day3」指定城市 一个点的可以dp出来 两个点也可以dp出来 后面的就是在两个点的情况下选一条最长的链加进去,用线段树维护即可 #include < ...

  6. 力扣Leetcode 1248. 统计「优美子数组」

    统计「优美子数组」 给你一个整数数组 nums 和一个整数 k. 如果某个 连续 子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」. 请返回这个数组中「优美子数组」的数目. 示例 ...

  7. 零元学Expression Design 4 - Chapter 3 看小光被包围了!!如何活用「Text On Path」设计效果

    原文:零元学Expression Design 4 - Chapter 3 看小光被包围了!!如何活用「Text On Path」设计效果 本章将教大家如何活用「Text On Path」,做出文绕图 ...

  8. 迄今为止最硬核的「Java8时间系统」设计原理与使用方法

    为了使本篇文章更容易让读者读懂,我特意写了上一篇<任何人都需要知道的「世界时间系统」构成原理,尤其开发人员>的科普文章.本文才是重点,绝对要读,走起! Java平台时间系统的设计方案 几乎 ...

  9. 教你用python搭建一个「生活常识解答」机器人

    今天教大家如何用Python爬虫去搭建一个「生活常识解答」机器人. 思路:这个机器人主要是依托于"阿里达摩院发布的语言模型PLUG",通过爬虫的方式,发送post请求(提问),然后 ...

随机推荐

  1. .net core 上传文件大小限制 webconfig

    <?xml version="1.0" encoding="utf-8"?><configuration> <location p ...

  2. mysql分库分表,做到永不迁移数据和避免热点

    作者:老顾聊技术   搜云库技术团队  来源:https://www.toutiao.com/i6677459303055491597 一.前言 中大型项目中,一旦遇到数据量比较大,小伙伴应该都知道就 ...

  3. afx.h(78): fatal error C1083: 无法打开包括文件: “new.h”: No such file or directory

    vs2015新建mfc工程,编译错误: D:\program files (x86)\microsoft visual studio 14.0\vc\atlmfc\include\afx.h(78): ...

  4. python vs vscode问题汇总

    最近在学工程目录章节的时候遭遇了个把 vscode目录管理 造成的问题, 当然第一大原因是: 初学者使用vscode的时候没有将环境设置好..... 闹了好几天的脾气, 这两天才整理好..... 这事 ...

  5. WPF RadioButton的绑定

    1. 枚举类 public enum EnumDataTypes { Simulation, Test } 2. 枚举型与布尔型的转换 public class EnumToBooleanConver ...

  6. JAVA基础复习与总结<七> File类_基本的IO概念_输入输出

    File类 1.操作目录  mkdir() 创建目录,必须确保父目录存在,如果不存在,创建失败 mkdirs() list() 文件:目录字符串形式 ,只返回目录和文件的名称 listFiles()  ...

  7. PBRT笔记(13)——光线传播1:表面反射

    采样反射函数 BxDF::Sample_f()方法根据与相应的散射函数相似的分布来选择方向.在8.2节中,该方法用于寻找来自完美镜面的反射和透射光线;在这里讲介绍实现其他类型的采样技术. BxDF:: ...

  8. CF76A.Gift [最小生成树]

    CF76A.Gift 题意:noi2014魔法森林弱化版QwQ,最小化\(max(g_i)*G + max(s_i)*S\)的最小生成树 考虑按g升序加边,用已在生成树中的边和新加入的边求当前最小生成 ...

  9. lua 语言基础

    1.数据类型: string(字符串) ·运算符“+.-.*./”等操作字符串,lua会尝试讲字符串转换为数字后操作: ·字符串连接用“..”运算符 ·用“#”来计算字符串的长度(放在字符串前面) · ...

  10. NOIP-比例简化

    题目描述 在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果.例如,对某一观点表示支持的有 1498 人,反对的有 902 人,那么赞同与反对的比例可以简单的记为 1498:902 . ...