前言

在前两次的 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. 【LOJ】#3036. 「JOISC 2019 Day3」指定城市

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

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

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

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

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

  7. 企业运营对 DevOps 的「傲慢与偏见」

    摘要:出于各种原因,并非所有人都信任 DevOps .有些人觉得 DevOps 只不过给开发者改善产品提供了一个途径而已,还有的人觉得 DevOps 是一堆悦耳的空头支票,甚至有人认为 DevOps ...

  8. Asp.net Mvc 请求是如何到达 MvcHandler的——UrlRoutingModule、MvcRouteHandler分析,并造个轮子

    这个是转载自:http://www.cnblogs.com/keyindex/archive/2012/08/11/2634005.html(那个比较容易忘记,希望博主不要生气的) 前言 本文假定读者 ...

  9. 「前端开发者」如何把握住「微信小程序」这波红利?

    由于前两周一直在老家处理重要事情,虽然朋友圈被「微信小程序」刷爆了,但并没有时间深入了解. 昨天回广州之后,第一件事情就是把「微信小程序」相关的文章.开发文档.设计规范全部看了一遍,基本上明白了「微信 ...

随机推荐

  1. 如何托管ASP.NET Core应用到Windows Service中

    (此文章同时发表在本人微信公众号"dotNET开发经验谈",欢迎右边二维码来关注.) 题记:正在构思一个中间件的设计,考虑是否既可以使用最新的技术,也可以兼顾传统的部署模式.所以有 ...

  2. spark spark ziliao important

    http://book.51cto.com/art/201408/448416.htm 一.如何实现多台机器的ssh无密码登录 当我们在配置多台计算,使之可以相互使用无密码登录-ssh,之前都是一台一 ...

  3. 线程安全集合 ConcurrentDictionary&lt;TKey, TValue&gt; 类

    ConcurrentDictionary<TKey, TValue> 类 [表示可由多个线程同时访问的键/值对的线程安全集合.] 支持 .NET Framework 4.0 及以上. 示例 ...

  4. ACM之Java速成(2)

    acm中Java的应用 Chapter I. Java的优缺点各种书上都有,这里只说说用Java做ACM-ICPC的特点: (1) 最明显的好处是,学会Java,可以参加Java Challenge ...

  5. Android中实现控件圆角边框

    首先,在drawable文件夹下新建一个xml文件: <?xml version="1.0" encoding="utf-8"?> <shap ...

  6. junit测试套件

    在实际项目中,随着项目进度的开展,单元测试类会越来越多,可是直到现在我们还只会一个一个的单独运行测试类,这在实际项目实践中肯定是不可行的.为了解决这个问题,JUnit 提供了一种批量运行测试类的方法, ...

  7. C# 带偏移量自定义分页方法

    /// <summary> /// 带偏移量自定义分页方法 /// </summary> /// <param name="PageSize"> ...

  8. List基础操作

    /** * List基础操作 * Created by zhen on 2018/11/14. */ object ListDemo { def main(args: Array[String]) { ...

  9. Python爬虫之PyQuery使用(六)

    Python爬虫之PyQuery使用 PyQuery简介 pyquery能够通过选择器精确定位 DOM 树中的目标并进行操作.pyquery相当于jQuery的python实现,可以用于解析HTML网 ...

  10. Spark 实践——用 Scala 和 Spark 进行数据分析

    本文基于<Spark 高级数据分析>第2章 用Scala和Spark进行数据分析. 完整代码见 https://github.com/libaoquan95/aasPractice/tre ...