SCF:简单配置外观
SCF 将代码与外部配置分离开。让代码使用一个属性,而不关心它在哪里/如何被配置!
引言
SCF(Simple Configuration Facade 的缩写)是 **代码** 和 **外部配置**(属性文件、env
变量、系统属性、yaml 文件等)之间的抽象。它就像 slf4j(Java 的简单日志外观)一样,在配置领域中占据着同样的位置。
SCF 将代码与外部配置分离开。让代码使用一个属性,而不关心它在哪里/如何被配置!
用法
- Java: https://github.com/mydotey/scf/tree/master/java
- .NET: https://github.com/mydotey/scf/tree/master/dotnet
示例
特点
强类型
核心抽象是 Property<K, V>
,具有强类型的键 (Key) 和强类型的值 (Value)。
安全
可以使用值过滤器来防止配置不好的属性值。
动态
每个属性都可以是动态的、可监听的,如果它动态变化的话。
多源
多个源可以协同工作,具有不同的优先级。属性值将根据其优先级自动计算。
可扩展
scf-core
只包含少数接口抽象和默认实现。所有核心概念都是可扩展的(配置管理器、配置源、属性等)。欢迎扩展默认实现或编写自己的新实现。
一些扩展
轻量级
不使用线程。只占用少量内存来缓存属性。
并发
所有管理器/属性 API 都是线程安全的,并且具有 O(1) 的复杂度,就像 ConcurrentHashMap
一样。
易于使用
scf-simple
提供了最常用、最简单的 Property<String, String>
的实现:属性文件、内存 Map、系统属性、env
变量等。
另请参阅
核心概念
属性
在 *代码* 中,一个配置项被独立使用,具有唯一的 *属性配置* 和一个 *强类型的值*。
*代码* 可以监听一个 *动态变化* 的属性的变化。动态属性的值由 *配置管理器* 自动更新。
属性配置
一个 *属性* 的配置包含以下部分
- 键 (Key):在 *配置管理器* 中唯一标识一个 *属性*,可以是 *字符串*,也可以是任何其他 *强类型对象*
- 值类型 (Value Type):属性的值的类型
- 默认值 (Default Value):当 *属性* 在任何 *配置源* 中都未配置时使用
- 值转换器 (Value Converter):将一个值转换为另一种类型,一个源有
<K, V1>
,但 *代码* 需要<K, V2>
,可以使用转换器<V1, V2>
自动将类型为V1
的值转换为类型为V2
的值 - 值过滤器 (Value Filter):有机会检查从 *配置源* 获取的值,主要用于 **验证** 该值
配置源
属性可以通过多种方式进行配置。例如,内存中的 HashMap
,或属性文件,或 env
变量,或 Java 系统属性,或 yaml 文件等。
多种方式可以一起使用!每种方式都是一个配置源。每个源负责为属性提供一个值。
有时,一个源无法提供值,会返回 null
(源中不存在该属性)。
- 该源无法识别键。例如,键类型是一个强类型对象
{ key: request.timeout, labels: { dc: aws-us-east1, app: 100000 } }
,但该源只接受String key
。 - 源中未配置该属性。
- 源中的属性值类型为
A
,但代码需要类型B
,并且在属性配置中未提供转换器<A, B>
。源也无法将A
转换为B
。
Configuration Manager
配置管理器是 *代码* 的配置外观。*代码* 从管理器获取属性,而不关心属性是如何/在哪里配置的。
根据需要,*代码* 可以拥有 1 个或多个管理器。每个组件可以有不同的管理器。管理器也可以在组件之间共享/传递。
管理器提供 2 种 API
<K, V> Property<K, V> getProperty(PropertyConfig<K, V> config)
:用于 **稳定** 的属性和 **稳定** 的键,返回一个 **唯一** 的属性对象。**管理器** 会维护这些稳定的属性,并在属性值发生变化时自动更新它们。**代码** 可以将其保存在某处并多次使用。<V> V getPropertyValue(PropertyConfig<K, V> config)
:用于 **非稳定** 的属性和 **非稳定** 的键。例如,访客 **IP** 被用作键的一部分,不知道应用有多少个这样的键,也不知道属性何时被配置和使用。
源与源优先级
一个管理器可以管理多个配置源。**不同的源具有不同的优先级。** 管理器按源优先级顺序从源中获取属性值。
核心概念关系
核心逻辑
开发版
- 赵强