Spring Framework 5.0 正式支持 Kotlin,Spring Boot 2.x 提供一流 Kotlin 整合體驗。Pivotal 團隊長期擁抱 JVM 多語言(Groovy、Scala),Kotlin 以空安全、協程、與 Java 100% 互操作成為首選。
<properties>
<kotlin.version>1.1.2</kotlin.version>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- Kotlin 標準庫 (JDK 8 版) -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jre8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<!-- 反射支持 (Spring 需要) -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>${kotlin.version}</version>
</dependency>
<!-- Jackson Kotlin 模塊 (序列化支持) -->
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
<!-- 源碼目錄配置 -->
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<!-- Kotlin 編譯插件 -->
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<configuration>
<compilerPlugins>
<plugin>spring</plugin> <!-- 開啟 Spring 插件:自動打開 final 類/方法 -->
</compilerPlugins>
<jvmTarget>1.8</jvmTarget>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals><goal>compile</goal></goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals><goal>test-compile</goal></goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
@SpringBootApplication
class KotlinDemoApplication
fun main(args: Array<String>) {
SpringApplication.run(KotlinDemoApplication::class.java, *args)
}
Kotlin 語法亮點:
@RestController
class HelloController(val helloService: HelloService) { // 主構造函數注入,無需 @Autowired
@GetMapping("/hello")
fun helloKotlin(): String = "hello world"
@GetMapping("/hello-service")
fun helloKotlinService(): String = helloService.getHello()
@GetMapping("/hello-dto")
fun helloDto(): HelloDto = HelloDto("Hello from the dto")
}
關鍵點:
@Service
class HelloService {
fun getHello(): String = "hello service"
}
data class HelloDto(val greeting: String) // 一行實現:equals/hashCode/toString/copy
data class 自動生成:`equals()`、`hashCode()`、`toString()`、`copy()`、`componentN()`,極大減少樣板代碼。
@RunWith(SpringRunner::class)
@SpringBootTest(classes = [KotlinDemoApplication::class], webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class KotlinDemoApplicationTests {
@Autowired
lateinit var testRestTemplate: TestRestTemplate // lateinit 非空斷言,延遲初始化
@Test
fun `whenCalled_shouldReturnHello`() {
val result = testRestTemplate.getForEntity("/hello", String::class.java)
assertNotNull(result)
assertEquals(HttpStatus.OK, result?.statusCode) // ?. 安全調用
assertEquals("hello world", result?.body)
}
@Test
fun `whenCalled_shouldReturnHelloService`() {
val result = testRestTemplate.getForEntity("/hello-service", String::class.java)
assertEquals("hello service", result?.body)
}
@Test
fun `whenCalled_shouldReturnJSON`() {
val result = testRestTemplate.getForEntity("/hello-dto", HelloDto::class.java)
assertEquals(HelloDto("Hello from the dto"), result?.body) // data class 結構化比較
}
}
空安全機制**:
| 特性 | Java 對比 | 收益 |
|---|---|---|
| 空安全 | 運行時 NPE | 編譯期消除 90% NPE |
| 數據類 | 手寫/IDE 生成 getter/setter/equals/hashCode | 一行代碼替換 50+ 行 |
| 擴展函數 | 工具類靜態方法 | 面向對象語法增強現有類 |
| 協程 | Future/CompletableFuture/Reactor | 同步寫法實現異步非阻塞 |
| 100% 互操作 | 混合編程困難 | 無縫調用 Java 庫,漸進式遷移 |
| 智能轉換 | 手動 instanceof + 強轉 | 類型檢查後自動轉換 |