KivaKit简介

2025/04/20

1. 概述

KivaKit是一个模块化Java应用程序框架,旨在让微服务和应用程序的开发更快、更轻松。KivaKit自2011年起由Telenav开发。目前,它已在GitHub上以Apache许可的开源项目形式提供。

在本文中,我们将探讨KivaKit作为一系列可协同工作的“迷你框架”的设计理念。此外,我们还将介绍每个迷你框架的基本功能。

2. KivaKit迷你框架

查看kivakitkivakit-extensions仓库,我们发现KivaKit 1.0包含54个模块,这或许会让人眼花缭乱。不过,如果我们一步步来,情况就不会那么糟糕。首先,我们可以选择想要添加到项目中的模块,KivaKit中的每个模块都设计为可独立使用。

一些KivaKit模块包含迷你框架,迷你框架是一种简单、抽象的设计,用于解决一个常见问题。如果我们仔细研究KivaKit的迷你框架,就会发现它们拥有简单易用且适用范围广泛的接口。因此,它们有点像乐高积木,也就是说,它们是由简单的零件拼凑而成的。

在这里,我们可以看到KivaKit的迷你框架以及它们之间的关系:

迷你框架 模块 描述
应用程序 kivakit-application 应用程序和服务器的基础组件
命令行解析 kivakit-commandline 使用转换和验证迷你框架进行开关和参数解析
组件 kivakit-component 实现KivaKit组件(包括应用程序)的基本功能
转换 kivakit-kernel 用于实现健壮的模块化类型转换器的抽象
提取 kivakit-kernel 从数据源提取对象
接口 kivakit-kernel 用作框架之间集成点的通用接口
日志记录 kivakit-kernel kivakit-logs-* 核心日志功能、日志服务提供商接口(SPI)和日志实现
消息传递 kivakit-kernel 使组件能够传输和接收状态信息
混合 kivakit-kernel 状态特征的实现
资源 kivakit-resource kivakit-network-*kivakit-filesystems-* 文件、文件夹和流资源的抽象
服务定位器 kivakit-configuration 用于查找组件和设置信息的服务定位器模式的实现
设置 kivakit-configuration 轻松访问组件配置信息
验证 kivakit-kernel 检查对象一致性的基本功能

我们可以在Kivakit仓库中找到这些框架,另一方面,我们会在kivakit-extensions中找到一些不太重要的模块,例如服务提供者。

2.1 消息传递

如上图所示,消息传递是集成的核心。在KivaKit中,消息传递使状态报告正式化,作为Java程序员,我们习惯于记录状态信息。有时,我们也会看到这些信息返回给调用者或作为异常抛出。相比之下,KivaKit中的状态信息包含在消息中,我们可以编写组件来广播这些消息。此外,我们还可以编写组件来监听这些消息。

我们可以看到,这种设计允许组件专注于一致地报告状态。对于组件来说,状态消息的去向并不重要。在一种情况下,我们可能会将消息定向到Logger。在另一种情况下,我们可能会将它们包含在统计信息中,我们甚至可以将它们显示给最终用户,组件并不关心,它只会向可能感兴趣的人报告问题。

广播消息的KivaKit组件可以连接到一个或多个消息中继器,形成监听器链:

在KivaKit中,Application通常是监听器链的末端。因此,Application类会记录它收到的所有消息。在此过程中,监听器链中的组件可能会将这些消息用于其他用途。

2.2 混合

KivaKit的另一个集成功能是mixins迷你框架,KivaKit mixins允许通过接口继承将基类“混合”到类型中。有时,mixins也被称为“有状态特征”。

例如,KivaKit中的BaseComponent类提供了构建组件的基础,BaseComponent提供了发送消息的便捷方法。此外,它还提供了对资源、设置和注册对象的轻松访问。

但我们很快就遇到了这种设计的问题,众所周知,在Java中,已经有基类的类不能扩展BaseComponent。KivaKit mixins允许将BaseComponent功能添加到已经有基类的组件中。例如:

public class MyComponent extends MyBaseClass implements ComponentMixin { [...] }

我们可以在这里看到接口ComponentMixin同时扩展了Mixin和Component:

Mixin接口为ComponentMixin提供了一个state()方法,首先,该方法用于创建一个BaseComponent并将其与实现ComponentMixin的对象关联起来。其次,ComponentMixin将Component接口的每个方法实现为Java默认方法。第三,每个默认方法都委托给关联的BaseComponent,这样,实现ComponentMixin提供的方法与扩展BaseComponent相同。

2.3 服务定位器

服务定位器类Registry允许我们将组件连接在一起,Registry提供的功能与依赖注入(DI)大致相同,但是,它与DI的典型用法在一个重要方面有所不同。在服务定位器模式中,组件会主动获取所需的接口,而DI则会将接口推送到组件中。因此,服务定位器方法改进了封装性,并减少了引用的范围。例如,Registry可以在方法中简洁地使用:

class MyData extends BaseComponent {

    [...]

    public void save() {
        var database = require(Database.class);
        database.save(this);
    }
}

这里的BaseComponent.require(Class)方法会在Registry中查找对象,当我们的save()方法返回时,数据库引用就会离开作用域,这确保了没有外部代码能够获取我们的引用。

应用启动时,我们可以使用BaseComponent.registerObject()方法注册服务对象。之后,应用中其他位置的代码可以通过require(Class)查找它们。

2.4 资源和文件系统

kivakit-resource模块提供了读写流资源和访问文件系统的抽象,我们可以在这里看到KivaKit包含的一些比较重要的资源类型:

  • 文件(本地、Zip、S3和HDFS)
  • 包资源
  • 网络协议(套接字、HTTP、HTTPS和FTP)
  • 输入和输出流

我们从这种抽象中获得了两个宝贵的好处,可以:

  • 通过一致的、面向对象的API访问任何流资源
  • 使用Resource和WritableResource接口允许使用未知的资源类型

2.5 组件

kivakit-component模块让我们可以轻松访问常用功能,我们可以:

  • 发送和接收消息
  • 访问包和打包资源
  • 注册和查找对象、组件和设置

BaseComponent和ComponentMixin都实现了Component接口,因此,我们可以为任何对象添加“组件特性”。

2.6 日志记录

KivaKit组件形成的监听器链通常终止于一个Logger,Logger将接收到的消息写入一个或多个Log中。此外,kivakit-kernel模块提供了一个用于实现Log的服务提供者接口(SPI)。

使用日志记录SPI,kivakit-extensions仓库为我们提供了一些日志实现:

提供者 模块
ConsoleLog kivakit-kernel
FileLog kivakit-logs-file
EmailLog kivakit-logs-email

可以从命令行选择并配置一个或多个日志,这通过定义KIVAKIT_LOG系统属性来实现。

2.7 转换和验证

kivakit-kernel模块包含用于类型转换和对象验证的微型框架,这些框架与KivaKit消息传递功能集成,这使得它们能够一致地报告问题,并简化了使用。要实现像StringConverter这样的类型转换器,我们需要编写转换代码,我们无需担心异常、空字符串或Null值。

我们可以在KivaKit的许多地方看到转换器的使用,包括:

  • 开关和参数解析
  • 从属性文件加载设置对象
  • 将对象格式化为调试字符串
  • 从CSV文件读取对象

Validatable广播的消息会被验证微框架捕获,随后,这些消息会被分析,以便我们轻松获取错误统计信息和验证问题。

k5

2.8 应用程序、命令行和设置

kivakit-application、kivakit-configuration和kivakit-commandline模块为开发应用程序提供了一个简单、一致的模型

kivakit-application项目提供了Application基类,Application是一个组件,它使用kivakit-configuration提供设置信息。此外,它还使用kivakit-commandline提供命令行解析。

kivakit-configuration项目使用kivakit-resource模块从.properties资源(以及将来的其他来源)加载设置信息,它使用kivakit-kernel转换器将这些资源中的属性转换为对象,然后使用Validation迷你框架对转换后的对象进行验证。

应用程序的命令行参数和开关由kivakit-commandline模块使用KivaKit转换器和验证器进行解析,我们可以在应用程序的ConsoleLog中看到出现的问题。

2.9 微服务

到目前为止,我们已经讨论了KivaKit中对任何应用程序都有用的功能。此外,KivaKit还在kivakit-extensions中提供了专门针对微服务的功能,让我们快速浏览一下kivakit-web

kivakit-web项目包含用于快速开发简单的REST和Web微服务接口的模块,JettyServer类为我们提供了一种轻松插入Servlet和过滤器的方法,JettyServer可以使用的插件包括:

插件 描述
JettyJersey REST应用程序支持
JettySwagger Swagger自动REST文档
JettyWicket 支持Apache Wicket Web框架

这些插件可以组合起来提供带有Swagger文档和Web界面的RESTful微服务:

var application = new MyRestApplication();
listenTo(new JettyServer())
    .port(8080)
    .add("/*", new JettyWicket(MyWebApplication.class))
    .add("/open-api/*", new JettySwaggerOpenApi(application))
    .add("/docs/*", new JettySwaggerIndex(port))
    .add("/webapp/*", new JettySwaggerStaticResources())
    .add("/webjar/*", new JettySwaggerWebJar(application))
    .add("/*", new JettyJersey(application))
    .start();

KivaKit 1.1将包含一个专用的微服务迷你框架,这将使我们更轻松地构建微服务。

3. 文档和Lexakai

KivaKit的文档由Lexakai生成Lexakai创建UML图(可根据需要使用注释引导)并更新README.md Markdown文件。在每个项目的README文件中,Lexakai都会更新标准的页眉和页脚。此外,它还维护生成的UML图和Javadoc文档的索引。

4. 构建KivaKit

KivaKit的目标是Java 11或更高版本的虚拟机(但可以从Java 8源代码中使用),我们可以在Maven Central上找到KivaKit模块的所有构件。但是,我们可能想要修改KivaKit或为开源项目做出贡献,在这种情况下,我们需要构建它。

首先,让我们设置Git、Git FlowJava 16 JDKMaven 3.8.1或更高版本。

首先,我们将kivakit仓库克隆到我们的工作区中:

mkdir ~/Workspace
cd ~/Workspace
git clone --branch develop https://github.com/Telenav/kivakit.git

接下来,我们将示例bash配置文件复制到我们的主文件夹:

cp kivakit/setup/profile ~/.profile

然后我们修改~/.profile以指向我们的工作区以及我们的Java和Maven安装:

export KIVAKIT_WORKSPACE=$HOME/Workspace 
export JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-16.jdk/Contents/Home 
export M2_HOME=$HOME/Developer/apache-maven-3.8.2

设置好配置文件后,我们确保正在运行bash(在macOS上,zsh现在是默认设置):

chsh -s /bin/bash

最后,我们重新启动终端程序并执行命令:

$KIVAKIT_HOME/setup/setup.sh

安装脚本会克隆kivakit-extensions和其他一些相关的仓库,之后,它会初始化git-flow并构建所有KivaKit项目。

5. 总结

在本文中,我们简要介绍了KivaKit的设计,并介绍了它提供的一些重要功能。KivaKit非常适合开发微服务,它被设计成易于理解、独立的组件,方便学习和使用。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章