领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多我借着在 SpringOne 平台(我在那里做了关于 Spring Fu 的第一个演讲)和 Kotlinconf 之间的短暂停留机会,概述了该项目的演进,总结了当前状态,并分享了未来的发展方向。
6 月初,我宣布了一个名为 Spring Fu 的新的实验性项目,其目标是尝试使用 Kotlin DSL 和函数式配置来配置 Spring 应用程序的新型 API。
今天,我很自豪地宣布一个新的实验性项目:Spring Fu。这是一个 @Kotlin 微框架,它使用函数式 API 而不是注解,可以轻松创建轻量级的 Spring 驱动的应用程序。我们期待您的反馈。 https://t.co/R15wJ1gD8K pic.twitter.com/ScljoPZ8rW
— Sébastien Deleuze (@sdeleuze) 2018 年 6 月 8 日
我必须承认,我没有预料到随后出现的巨大反馈浪潮,并且我要感谢 Spring 社区给予的热烈欢迎。从那时起,我一直在继续开发该项目,以便将这个基于原始 Spring 框架 API 的第一个概念验证转变为 Spring 新函数特性孵化器。
Kotlin DSL 现在基于 Spring Boot 基础设施,并被称为 Kofu(Kotlin 和 functional 的缩写)。它允许使用 Kotlin DSL 和 Lambda 表达式而不是注解来配置 Spring Boot 应用程序,并具有以下特性:
使用 Kofu 配置的典型 Spring Boot 应用程序如下所示
val app = application {
import(beans)
listener<ApplicationReadyEvent> {
ref<UserRepository>().init()
}
properties<SampleProperties>("sample")
server {
port = if (profiles.contains("test")) 8181 else 8080
mustache()
codecs {
string()
jackson {
indentOutput = true
}
}
import(::routes)
}
mongodb {
embedded()
}
}
val beans = beans {
bean<UserRepository>()
bean<UserHandler>()
}
fun routes(userHandler: UserHandler) = router {
GET("/", userHandler::listView)
GET("/api/user", userHandler::listApi)
GET("/conf", userHandler::conf)
}
fun main() = app.run()
为了使用它,您“只需”将 org.springframework.fu:spring-boot-kofu
依赖项添加到 Spring Boot 2.1 应用程序中。正如当前版本号 0.0.2
所表明的那样,请注意,目前 API 尚未稳定,不适合生产环境,并且范围仅限于 Spring Boot 支持的一小部分。
但请随意尝试,发送反馈并尝试这种配置 Spring Boot 应用程序的新方法,它具有函数式特性,可以通过您的 IDE 自动完成进行发现,并且 有文档记录。
Kofu 并不比自动配置更好或更差,它只是不同。我相信它可能是 Spring Boot 触达那些更喜欢更显式配置模型的开发者以及来自其他背景(如 Kotlin、Go、Node 或 Ruby)的开发者的途径。
最初仅限于 Kotlin,我收到的主要反馈之一来自对这种显式 DSL 方法感兴趣的 Java 开发人员,因此我开发了一个 Java 等价物,最终得到了这个 Jafu(Java 和 functional 的缩写)DSL。
public class JafuApplication {
public static SpringApplication app = application(app -> {
app.beans(beans -> {
beans.bean(SampleService.class);
beans.bean(SampleHandler.class);
});
app.server(server -> server.router(router -> {
SampleHandler sampleHandler = app.ref(SampleHandler.class);
router.GET("/", sampleHandler::hello);
router.resources("/**", new ClassPathResource("static/"));
}));
});
public static void main (String[] args) {
app.run(args);
}
}
这目前只是一个概念验证,但我计划很快与 Kofu 实现功能奇偶校验,并并行开发这两个 DSL。由于缺少 类型安全的构建器、具现化的类型参数 或 扩展机制,Jafu 将比 Kofu 更加冗长且扩展性较差,但尽管存在这些限制,我仍然认为 Jafu 非常不错且易于使用。
对于仅对与使用函数式 Bean 注册基础设施相关的性能提升感兴趣的用户,值得注意的是,Dave Syer 目前正在 尝试 解决方案,这些解决方案将使基于注解的常规 Spring Boot 应用程序能够利用函数式 Bean 注册效率。
GraalVM 是 Oracle 开发的一种新的虚拟机,它允许(除其他功能外)通过 Substratevm 将 JVM 字节码编译为原生可执行文件。
Spring Framework 5.1 为 GraalVM 原生镜像提供了一些 初始支持,但我们才刚刚起步。GraalVM 团队需要修复 Dave 提出的各种问题才能使一切按预期工作,并且生态系统需要适应这个具有不同约束和特性的新平台。
但 GraalVM 团队正在倾听我们的反馈,并且 Spring 应用程序支持在最近几个月取得了长足的进步。现在已经可以将使用 Kofu 配置的基本 Spring Boot 响应式应用程序编译为原生可执行文件,并且几乎可以立即运行!
我在杜勒斯机场玩 Spring Fu。
— Toshiaki Maki (@making) 2018 年 9 月 28 日
看看它有多快!太疯狂了…… pic.twitter.com/CTyKEr4d4O
如前所述,Spring Fu 的主要目标是孵化将集成到当前顶级项目(如 Spring Framework、Spring Data 和 Spring Boot)中的特性。
Spring Fu 目前正在孵化 Spring WebFlux 和 Spring Data 的协程支持,以便能够以更具命令式的方式利用 Spring 响应式堆栈。这主要针对希望利用此类堆栈的可扩展性而不必使用所有响应式 API 功能的开发者。
class UserRepository(private val mongo: CoroutinesMongoTemplate) {
suspend fun count(): Long = mongo.count<User>()
suspend fun findAll(): List<User> = mongo.findAll<User>()
suspend fun findOne(id: String): User? = mongo.findById<User>(id)
suspend fun deleteAll() = mongo.remove<User>()
suspend fun save(user: User): User? = mongo.save(user)
}
请注意,虽然从 Kotlin 1.3 开始协程被认为是最终版本,但 kotlinx-coroutines
仍然缺少一个主要部分,因为它没有提供任何处理冷流的类型。为了能够使用协程 API 公开我们的响应式基础,我们将需要这个缺失的抽象,有关更多详细信息,请参阅 kotlinx.coroutines#254。
请注意,我们应该能够 在协程和 Reactor 类型之间传递上下文,以便允许非常强大的用例,例如响应式安全和事务。
Konrad Kaminski 通过他出色的 spring-kotlin-coroutine 项目贡献了最初的 Spring 协程支持,他很快将加入 Spring Fu 与我一起开发此特性。
我刚刚发布了 Spring Fu 0.0.2,它提供了改进的 Kofu DSL 并引入了 函数参数的自动装配。请随意尝试并提供反馈。
即将发布的 Spring Fu 0.0.3 将在 Kofu 和 Jafu 配置之间提供功能奇偶校验。
我们已经拥有 10 多位社区贡献者 向 Spring Fu 提交了拉取请求,因此如果您有一些想法,您也许可以成为下一个 ;-)
期待在即将举行的 Spring Fu 演讲中与您见面,地点包括 JFuture(明斯克)、Spring Fest(东京)和 Devoxx(安特卫普)。