Spring Fu 的演進

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

我藉由 SpringOne platform(我在那裡發表了關於 Spring Fu 的首次演講)和 Kotlinconf 之間的短暫停留,來概述該專案的演變,總結當前狀態並分享下一步可能的發展。

六月初,我宣布了一個名為 Spring Fu 的新實驗性專案,目標是嘗試一種新的 API,使用 Kotlin DSL 和函數式配置來配置 Spring 應用程式。

我必須承認,我沒想到會收到如此巨大的回饋,我想感謝 Spring 社群如此熱烈的歡迎。此後,我一直致力於該專案,以便將這個基於原始 Spring Framework API 的第一個 POC 轉變為新 Spring 函數式功能的孵化器。

Kofu 配置

Kotlin DSL 現在基於 Spring Boot 基礎架構,稱為 Kofu(代表 Kotlin 和 functional)。 它允許使用 Kotlin DSL 和 lambdas 而不是註解來配置 Spring Boot 應用程式,並具有以下特徵:

  • 通過 Kotlin DSL 進行顯式配置
  • 基於以函數方式使用的 Spring Boot 基礎架構
  • 沒有基於類別路徑檢測啟用的功能
  • 聲明式和程式化的
  • 更快的啟動速度和更低的記憶體消耗
  • 最小的反射和註解使用
  • 純 lambdas,沒有 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,我收到的主要回饋之一是來自 Java 開發人員,他們也對這種顯式 DSL 方法感興趣,因此我開發了一個 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);
  }
}

這目前只是一個 POC,但我計劃很快達到與 Kofu 相同的功能,並平行開發這兩個 DSL。 缺乏類型安全的 builder具體化的類型參數擴展機制將使 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 Reactive 堆疊。 這主要針對希望利用此類堆疊的可擴展性,而無需反應式 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 提交了 pull request,所以如果您有一些想法,您可能就是下一個 ;-)。

期待在即將在 JFuture (明斯克)、Spring Fest (東京) 和 Devoxx (安特衛普) 舉行的 Spring Fu 講座中與您會面。

取得 Spring 電子報

透過 Spring 電子報保持聯繫

訂閱

取得領先優勢

VMware 提供培訓和認證,以加速您的進展。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將舉行的活動

查看 Spring 社群中所有即將舉行的活動。

檢視全部