Spring Fu 的演进

工程 | Sébastien Deleuze | 2018 年 10 月 2 日 | ...

我借着在 SpringOne 平台(我在那里做了关于 Spring Fu 的第一个演讲)和 Kotlinconf 之间的短暂停留机会,概述了该项目的演进,总结了当前状态,并分享了未来的发展方向。

6 月初,我宣布了一个名为 Spring Fu 的新的实验性项目,其目标是尝试使用 Kotlin DSL 和函数式配置来配置 Spring 应用程序的新型 API。

我必须承认,我没有预料到随后出现的巨大反馈浪潮,并且我要感谢 Spring 社区给予的热烈欢迎。从那时起,我一直在继续开发该项目,以便将这个基于原始 Spring 框架 API 的第一个概念验证转变为 Spring 新函数特性孵化器。

Kofu 配置

Kotlin DSL 现在基于 Spring Boot 基础设施,并被称为 Kofu(Kotlin 和 functional 的缩写)。它允许使用 Kotlin DSL 和 Lambda 表达式而不是注解来配置 Spring Boot 应用程序,并具有以下特性:

  • 通过 Kotlin DSL 进行显式配置
  • 基于以函数式方式使用的 Spring Boot 基础设施
  • 不基于类路径检测启用任何特性
  • 既支持声明式也支持编程式
  • 更快的启动速度和更低的内存消耗
  • 最少的反射和注解使用
  • 纯 Lambda 表达式,没有 CGLIB 代理

使用 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)的开发者的途径。

Jafu 配置

最初仅限于 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 注册效率。

将 Spring 应用程序作为原生可执行文件运行

GraalVM 是 Oracle 开发的一种新的虚拟机,它允许(除其他功能外)通过 Substratevm 将 JVM 字节码编译为原生可执行文件。

Spring Framework 5.1 为 GraalVM 原生镜像提供了一些 初始支持,但我们才刚刚起步。GraalVM 团队需要修复 Dave 提出的各种问题才能使一切按预期工作,并且生态系统需要适应这个具有不同约束和特性的新平台。

但 GraalVM 团队正在倾听我们的反馈,并且 Spring 应用程序支持在最近几个月取得了长足的进步。现在已经可以将使用 Kofu 配置的基本 Spring Boot 响应式应用程序编译为原生可执行文件,并且几乎可以立即运行!

协程支持

如前所述,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(安特卫普)。

获取 Spring 新闻通讯

与 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获得支持

Tanzu Spring 在一个简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部