在 JavaOne 2014 之后,当配置主题从 EE8 列表中取消时,David Blevins 等人提出启动一个 Apache 项目的原因有几个:
- 让对该主题有经验的人确定一个共同的特征集。
- 将想法作为 Apache 项目的一部分实施,以使用免费和可再分发的许可证提供想法。
- 使用同样能够成功采用的经过验证的通用组织。这是 Apache Tamaya 开始孵化的时候。接下来我们进行了几次讨论、视频群聊和电子邮件。因此, Apache Tamaya 现在作为第一个版本 0.1-incubating 可用,可以使用了。
还值得一提的是,Deltaspike 背后的人 Mark Struberg 和 Gerhard Petracek 加入了这个项目并为之做出了积极贡献。我认为深入了解该项目是值得的。这就是这个博客的全部内容。
Apache Tamaya 项目
类似于 Java 规范请求
Apache Tamaya 的构建类似于 Java 规范请求 (JSR)。它作为一个 API 定义了用户通常与之交互的工件,并提供了一个实现 API 的参考实现,因此它可以用于现实世界的项目。这样做的原因如下:
- 将 API 与实现分开可以让您对问题有一个非常清晰的认识。您必须隔离问题的本质并忽略所有过于具体的方面。如果以一种好的方式完成,这将导致一个简单而全面的 API,同时它足够强大以支持至少大多数或所有其他要求(例如,使用扩展点或插件挂钩)适应或附加功能(又名服务提供商接口/SPI)。
- 在兼容性要求方面,API 可能比参考实现更独立。例如,Apache Tamaya 基于 Java 7 的 API 实际上也兼容 Java 6 和 Java ME 平台。
- 您可以从 API 上的一组最小功能开始,然后根据需要逐步扩展它。必须检查每个扩展,如果确实有必要,或者如果使用现有的 API/SPI 也不能实现要求。这确保您的 API 真正专注于最小的方面,因此变得精简和清晰。
- 最后但同样重要的是,与上一点相对应的是,添加新功能不会干扰基本 API/实现,因此添加新功能非常容易。 Apache Tamaya 项目还包含相当多的仅依赖于 API 的所谓扩展,因此该项目已经证明能够非常有效地涵盖这方面。
与 JSR 的唯一区别是当前缺少技术兼容性工具包 (TCK),该工具包可确保 API 的不同实现与一组通用规则兼容。同样,我们没有类似“规范”的东西(但我们有非常广泛的文档,在某种程度上与规范非常相似,还涵盖了 2 年前 Java EE JSR 评估阶段完成的许多方面/讨论)。
兼容性
Apache Tamaya 目前同时支持 Java 7 和 Java 8。这背后的原因是仍然有大量代码运行在 Java 7 上,尤其是在企业环境中。我们希望人们在转向之前能够使用 Apache Tamaya Java 8 平台。也就是说,API 可以很容易地添加到您的 Maven 构建中:
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
或者,当它与 Java 8 一起使用时:
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
类似地,可以添加实现模块(称为 core ),例如,对于 Java 7 及更高版本:
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
与 Java 8 兼容:
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
主要概念
配置抽象和访问
主要目标之一是为配置定义一个抽象,并定义一种使用简单 Java 代码访问它的通用方法。所以首先要定义一个模型进行配置:
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
因此,查看此界面可以确定一些重要的关键决策:
- 使用 字符串 键访问 配置 条目。
- 配置 值基本上建模为 字符串。
- 使用 Class 或 TypeLiteral 也支持类型化访问。
- 可以逐个键或通过访问完整的属性映射 ( getProperties ) 来访问 配置 。因此有一个约束,即返回的地图可能不包含所有条目,这些条目在单独访问它们时也可用。原因是某些配置源可能无法列出所有条目(也称为可 扫描 )。
- 带有查询的 方法定义了所谓的功能扩展点,允许将附加功能添加为可应用于配置的运算符/查询。
- 最后,仅在依赖于 Java 8 的 API 版本中定义,所有方法都返回 Optional 值。这些添加了对 Java 8 引入的新 可选 工件的支持。类似地,所有默认方法在 Java 7 变体中都被替换为参考实现附带的相应抽象基础实现。
可以从 ConfigurationProvider 单例访问 配置 实例:
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
因此,必须始终返回一个有效的实例。 不需要 总是返回相同的实例。特别是在上下文环境中运行时,例如 Java EE,每个上下文可能返回不同的配置,也反映了部署在不同 Java EE 工件中的配置资源。类似地,基于 OSGI 的环境也有自己的类加载器层次结构,这可能需要沿着类加载器边界隔离配置。
功能扩展点
在上一节中,我们已经提到了 with 和 query 方法。它们将 ConfigurationOperator 或 ConfigurationQuery<T> 作为参数,其定义如下:
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
所以基本上 ConfigOperator 充当从另一个 Configuration 派生 Configuration 的 映射,而 ConfigurationQuery<T> 可以返回任何类型的结果。两种构造都允许以多种方式添加功能,而无需在配置界面上处理它,例如:
- 过滤特定用例的配置,例如重新组合条目,或删除超出特定用例范围的条目
- 出于安全原因屏蔽条目或部分
- 基于配置创建类型化对象
- 给定配置的统计详细信息,例如定义的部分
- 配置验证和文档
- 配置的转换,例如转换为 JSON 表示
- 以及更多。
对于运行示例,您可以考虑查看 tamaya-functions 扩展模块,它已经实现了很多方面。
一个简约的例子
为了更清楚地说明问题,让我们创建一个小示例,它只使用 Tamaya 的核心实现提供的基本机制。假设我们构建了一个小节点,微服务执行简单的复合利率计算(我将省略财务细节,请参阅 https://en.wikipedia.org/wiki/Compound_interest 了解更多详细信息)。
我们假设利率是为此组件配置的东西,因此在我们的组件中我们只需添加以下代码:
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
在使用 Java 8 时,我们还可以轻松地将它与默认值结合起来:
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
假设我们可以轻松实现我们的业务逻辑,也可以使用 JSR 354 类型(请参阅 http://javamoney.org/ ):
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
现在假设您已经以类似的方式构建了您的逻辑,您可以部署计算器
- ...作为桌面应用程序的一部分。
- ... 作为 Java EE 应用程序的一部分。
- ...在 OSGI 容器中。
- ... 很容易作为独立的微服务(使用适当的 API,例如 REST)。
使 Tamaya 支持可选
基本上,您甚至可以使用 Tamaya 可选模块仅作为可选依赖项与 Tamaya 集成。这个扩展模块是一个非常简单的模块,基本上只添加一个类到你的依赖路径,它
- 确保 Tamaya API 在你的类路径中
- 可选地检查是否可以从给定上下文访问 配置 。
- 在创建委托时将 配置 请求委托给 Tamaya,或者 - 如果不可用 - 委托给从您的逻辑传递的委托:
<dependency>
<groupId>org.apache.tamaya</groupId>
<artifactId>tamaya-java7-api</artifactId>
<version>0.1-incubating</version>
</dependency>
这允许您支持 Tamya Configuration ,但如果您的目标环境中未加载 Tamaya,您仍然可以默认使用自己的默认配置逻辑。
还有什么?
从 API 的角度来看,不需要更多。之前使用的 TypeLiteral 类是相同的,它在 Java EE (CDI) 中也广为人知,唯一未提及的其他工件是 ConfigException 类。当然,这个功能本身是非常简约的,但它确实做到了它应该做的:它 为配置提供了一个简约的访问 API 。为什么我们认为这如此重要?原因如下:
- 每个编写组件的人通常都会编写一些配置逻辑,但每个人的做法都不一样:不同的格式、位置、密钥方案、覆盖等。此外,Apache Tamaya 既不想定义你配置的 内容 ,也不想定义你的配置位于 何处 以及如何 覆盖 它。但是我们定义了一个通用的 API 来访问配置。
- 考虑到来自不同团队的组件可以更容易地集成到一个项目中,但也可以集成到一个具体的企业环境中,因为所有组件都引用相同的配置机制。
- 更好的是,当使用 Tamaya 时,可以或多或少地忽略配置的 覆盖 规则,因为 Tamaya 的机制(我将在下一篇博客中介绍相应的 SPI)已经提供了这些机制,因此可以根据需要进行调整。
- 类似地,用于配置的 格式 以及配置可以本地存储在文件系统中或 远程 分发的事实也不再重要。
这本身应该使 Apache Tamaya 成为任何应用程序或模块架构中非常有趣和关键的一部分。此外,它的 SPI 带来了额外的好处,尤其是在更大的企业环境中。我们将在此处的下一篇博客文章中查看 SPI 和扩展。敬请期待!
一如既往,欢迎评论。如果有人也想为该项目做出贡献,请通过 mailto:dev@tamaya.incbuator.apache.org 与我们联系。
当然,帮助我们传播这个词,写推文、博客,采用它,使用它,爱上它!
想听更多?
想了解更多关于 Apache Tamaya 的信息吗?访问我们的 项目网站 ,或者更好地加入并看到我们
- 布达佩斯 Apache Con Europe 2015 (Anatole Tresch 和 Werner Keil)
- DevoXX 摩洛哥 (Werner Keil)