50、Kotlin 支持

Kotlin 是一种针对 JVM(和其他平台)的静态类型语言,它可编写出简洁而优雅的代码,同时提供与使用 Java 编写的现有库的互操作性

Spring Boot 通过利用其他 Spring 项目(如 Spring Framework、Spring Data 和 Reactor)的支持来提供 Kotlin 支持。有关更多信息,请参阅 Spring Framework Kotlin 支持文档

开始学习 Spring Boot 和 Kotlin 最简单方法是遵循这个全面教程。您可以通过 start.spring.io 创建新的 Kotlin 项目。如果您需要支持,请免费加入 Kotlin Slack 的 #spring 频道或使用 Stack Overflow 上的 springkotlin 标签提问。

50.1、要求

Spring Boot 支持 Kotlin 1.2.x。要使用 Kotlin,classpath 下必须存在 org.jetbrains.kotlin:kotlin-stdliborg.jetbrains.kotlin:kotlin-reflect。也可以使用 kotlin-stdlib 的变体 kotlin-stdlib-jdk7kotlin-stdlib-jdk8

由于 Kotlin 类默认为 final,因此您可能需要配置 kotlin-spring 插件以自动打开 Spring-annotated 类,以便可以代理它们。

在 Kotlin 中序列化/反序列化 JSON 数据需要使用 Jackson 的 Kotlin 模块。在 classpath 中找到它时会自动注册。如果 Jackson 和 Kotlin 存在但 Jackson Kotlin 模块不存在,则会记录警告消息。

提示

如果在 start.spring.io 上创建 Kotlin 项目,则默认提供这些依赖项和插件。

50.2、Null 安全

Kotlin 的一个关键特性是 null 安全。它在编译时处理空值,而不是将问题推迟到运行时并遇到 NullPointerException。这有助于消除常见的错误来源,而无需支付像 Optional 这样的包装器的成本。Kotlin 还允许使用有可空值的,如 Kotlin null 安全综合指南中所述。

虽然 Java 不允许在其类型系统中表示 null 安全,但 Spring Framework、Spring Data 和 Reactor 现在通过易于使用的工具的注解提供其 API 的安全性。默认情况下,Kotlin 中使用的 Java API 类型被识别为放宽空检查的平台类型Kotlin 对 JSR 305 注解的支持与可空注解相结合,为 Kotlin 中 Spring API 相关的代码提供了空安全。

可以通过使用以下选项添加 -Xjsr305 编译器标志来配置 JSR 305 检查:-Xjsr305={strict|warn|ignore}。默认行为与 -Xjsr305=warn 相同。在从 Spring API 推断出的 Kotlin 类型中需要考虑 null 安全的 strict 值,但是应该使用 Spring API 可空声明甚至可以在次要版本之间发展并且将来可能添加更多检查的方案。

警告

尚不支持泛型类型参数、varargs 和数组元素可空性。有关最新信息,请参见 SPR-15942。另请注意,Spring Boot 自己的 API 尚未注解

50.3、Kotlin API

50.3.1、runApplication

Spring Boot 提供了使用 runApplication<MyApplication>(*args) 运行应用程序的惯用方法,如下所示:

  1. import org.springframework.boot.autoconfigure.SpringBootApplication
  2. import org.springframework.boot.runApplication
  3. @SpringBootApplication
  4. class MyApplication
  5. fun main(args: Array<String>) {
  6. runApplication<MyApplication>(*args)
  7. }

这是 SpringApplication.run(MyApplication::class.java, *args) 的替代方式。它还允许自定义应用程序,如下所示:

  1. runApplication<MyApplication>(*args) {
  2. setBannerMode(OFF)
  3. }

50.3.2、扩展

Kotlin 扩展提供了使用附加功能扩展现有类的能力。Spring Boot Kotlin API 利用这些扩展为现有 API 添加新的 Kotlin 特定便利。

提供的 TestRestTemplate 扩展类似于 Spring Framework 为 RestOperations 提供的。除此之外,扩展使得利用 Kotlin reified 类型参数变为可能。

50.4、依赖管理

为了避免在 classpath 上混合不同版本的 Kotlin 依赖项,提供了以下 Kotlin 依赖项的依赖项管理:

  • kotlin-reflect
  • kotlin-runtime
  • kotlin-stdlib
  • kotlin-stdlib-jdk7
  • kotlin-stdlib-jdk8
  • kotlin-stdlib-jre7
  • kotlin-stdlib-jre8

使用 Maven,可以通过 kotlin.version 属性自定义 Kotlin 版本,并为 kotlin-maven-plugin 提供插件管理。使用 Gradle,Spring Boot 插件会自动将 kotlin.version 与 Kotlin 插件的版本保一致。

50.5、@ConfigurationProperties

@ConfigurationProperties 目前仅适用于 lateinit 或可空的 var 属性(建议使用前者),因为尚不支持由构造函数初始化的不可变类。

  1. @ConfigurationProperties("example.kotlin")
  2. class KotlinExampleProperties {
  3. lateinit var name: String
  4. lateinit var description: String
  5. val myService = MyService()
  6. class MyService {
  7. lateinit var apiToken: String
  8. lateinit var uri: URI
  9. }
  10. }

提示

要使用注解处理器生成您自己的元数据,应使用 spring-boot-configuration-processor 依赖配置 kapt

50.6、测试

虽然可以使用 JUnit 4(spring-boot-starter-test 提供的默认配置)来测试 Kotlin 代码,但建议使用 JUnit 5。JUnit 5 允许测试类实例化一次,并在所有类的测试中复用。这使得可以在非静态方法上使用 @BeforeAll@AfterAll 注解,这非常适合 Kotlin。

要使用 JUnit 5,请从 spring-boot-starter-test 中排除 junit:junit 依赖项,然后添加 JUnit 5 依赖项,并相应地配置 Maven 或 Gradle 插件。有关更多详细信息,请参阅 JUnit 5 文档。您还需要将测试实例生命周期切换为 per-class

为了模拟 Kotlin 类,建议使用 Mockk。如果需要 Mockk 等效的 Mockito 特定的 @MockBean@SpyBean 注解,则可以使用 SpringMockK,它提供类似的 @MockkBean@SpykBean 注解。

50.7、资源

50.7.1、进阶阅读

50.7.2、示例