Spring Boot 實踐折騰記(14):使用Kotlin
博爾赫斯說,沒有比思考更復雜的思考了,因此我們樂此不疲。
從Spring Boot 2開始,Boot也開始正式支援Kotlin程式設計,我們可以在建立Spring Boot應用時程式時使用Spring初始化Kotlin,不過Kotlin要在新的Spring 5版本中才得到支援。
Kotlin
Kotlin(https://kotlinlang.org/)是一個基於JVM的靜態型別程式語言,由JetBrains公司(也就是程式設計師現在常用的IDEA工具的公司)定義和開發。 Kotlin的一個關鍵目標是能與Java進行互操作,以便在同一個專案中可以同時使用Java和Kotlin。
先來看一個由Kotlin編寫簡單的Hello World程式,如下程式碼:
fun main(args: Array<String>){
println("Hello World");
}
在Kotlin中,沒有像Java那樣的static靜態方法,所以我們只能編寫fun聲名符,並將它作為類裡的一個靜態方法來使用才行,後者單獨作為一個函式類來使用。
Classes
Kotlin中的類class與Scala類很相似,它們都有一個類名,並帶有一個主建構函式和一個或多個次要建構函式。
class Person(val firstname: String,val lastname: String) {
constructor(name: String) : this (name, "")
fun printDetails() = println("FirstName: ${firstname}, LastName: ${lastname}")
}
Interfaces
Kotlin中的介面類似於Java 8中的介面,它們都可以包含有具有抽象方法宣告以及預設實現的方法。
interface ReportSender
{
fun generateReport() : String
fun sendReport() {
val report = generateReport()
println("Report: " + report)
}
}
Data Classes
在Java中,通常我們會使用私有屬性加setter和getter的方式來建立為POJO(普通Java物件)。 然後自定義或由類庫紫星實現實現equals(),hashCode()和toStirng()等方法。而Kotlin是通過使用資料類(Data Classes)來建立這樣的類。比如:
data class Person(val name: String, val email: String)
只需將類宣告為資料類,Kotlin的編譯器就會自動生成equals(),hashCode()和equals()方法。有興趣的同學通過https://kotlinlang.org/docs/reference/瞭解有關Kotlin的更多詳細資訊。
實戰:在Spring Boot中使用Kotlin
好了,我們還是說回Spring Boot,首先,建立一個Spring Boot的應用,引入web-starter依賴:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
我們也可以使用IDE或http://start.spring.io建立Spring Boot應用程式,只是語言型別要選擇Kotlin,們目前IDEA是預設支援建立的。
其次,在建立成功後,我們還需要引入編譯外掛,以Maven為例,需要kotlin-maven-plugin,目的是為了使用src / main / kotlin和src / test / kotlin分別作為主要和測試原始碼資料夾路徑。 見如下POM清單:
dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jre8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
。。。
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<source>src/main/java</source>
<source>src/main/kotlin</source>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<source>src/test/java</source>
<source>src/test/kotlin</source>
</sourceDirs>
</configuration>
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
這裡有個小技巧,如果使用的是IDEA,可以選擇工程配置,自動增加maven依賴,kotlin.version我們就選最新的1.2.41。
還有,Kotlin會預設選擇開啟Spring框架的註解支援(比如,用@Configuration註解的類,@Service,@Component,@Repository等),但並不是必須的,可以根據選擇引入。這裡要特別注意一點,如果想在Kotlin中建立一個非final的類,我們則需要在類中新增open修飾符,比如:
open class Application {
}
比如,我們通常會使用的註釋類 ,@Component,@Async,@Transactional和@ Cacheable ,@Configuration,@Controller,@RestController,@Service和@ Repository等等,這些類在Kotlin中都會自動開啟。 這些配置在初始化過程中,都會被kotlin-spring外掛預設配置。
第一步,建立一個Rest API控制器HomeController.kt,如下所示:
@RestController
class ManController(val manService:ManService) {
@GetMapping("/ok")
fun home(): String {
val man = manService.findByName("mickjoust")
return "ok ==> kotlin"+"name:"+man.name
}
}
第二步:建立示例類Man.kt,如下所示:
class Man(
var id: Int = -1,
var name: String = "",
var email: String = ""
) {
override fun toString(): String {
return "Man(id=$id, name='$name', email='$email')"
}
}
注意,因為語法差異,主建構函式是直接寫在類名後,用()表示,過載toString()語法也不同,可以使用IDE自動生成。
第三步,我們建立一個簡單的查詢服務,包含一個介面定義類ManService.kt和介面實現類,程式碼如下:
interface ManService {
fun findByName(name: String): Man
}
@Service
class ManServiceImpl : ManService {
override fun findByName(name: String): Man {
return Man(1,name,"12323131313")
}
}
最後一步,建立主啟動類BootKotlinApp.kt,如下所示:
@SpringBootApplication
class BootKotlinApp fun main(args: Array<String>) {
SpringApplication.run(BootKotlinApp::class.java, *args);
}
以上程式碼中,我們將main()方法建立為頂級函式。這點和java裡的static有一點區別。到這裡,執行會報錯!錯誤為:
org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
@Configuration class ‘BootKotlinApp’ may not be final.
Remove the final modifier to continue.
我們注意到@Configuration因為使用了final,前面我們說到,在kotlin中預設類都有final標示,要建立需要使用open欄位,我們需要加上,這點和java也是有區別的。修改為:
open class BootKotlinApp fun main(args: Array<String>) {
重新執行,成功! 訪問hlocalhost:8080/ok,返回:
ok ==> kotlinname:mickjoust
小結
本文主要討論瞭如何使用基於JVM的語言Kotlin建立Spring Boot應用程式,Kotlin現在越來越受到更多人的使用,也成為了安卓開發的有利工具,對於後端開發可能涉及較少,但是,每一次實戰都可以增強我們的動手能力,這才是最重要的。