領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多更新:現已提供一份全面的 Spring Boot + Kotlin 教程。
恰逢 Kotlin 1.0 釋出,我們在 https://start.spring.io 中增加了對 Kotlin 語言的支援,以便更輕鬆地使用該語言啟動新的 Spring Boot 專案。
這篇博文也給了我一個機會,解釋為什麼我認為這種語言很有趣,向您詳細展示一個示例專案,併為您提供一些技巧。
Kotlin 是由 JetBrains 建立的一種語言。它執行在 JVM 之上(但不僅限於 JVM),它是一種面向物件的語言,融合了許多函數語言程式設計的思想。我不會過多地介紹 Kotlin 的所有特性(PDF,HTML),但我希望重點介紹我發現最有趣的那些特性。
您可以在這篇 Kotlin 2015 摘要 的博文中找到許多有助於提高 Kotlin 知識的有用連結。還可以看看這些簡單的 Kotlin 練習,快速瞭解該語言。
Kotlin 的設計旨在與 Java 生態系統良好協作,在我看來,它與 Spring Boot 擁有相同的務實、創新和固執己見的理念,因此它們可以很好地協同工作。您可以檢視這個簡單的 Spring Boot + Spring Data JPA Kotlin 專案,更具體地瞭解它的樣子。
Kotlin 憑藉其非常簡潔的 類 宣告語法,可以輕鬆編寫(和閱讀)您的領域模型。您可以看到 Kotlin 允許您指定引數的預設值,並且型別在變數/引數名稱之後宣告。
@Entity
class Customer(
var firstName: String = "",
var lastName: String = "",
@Id @GeneratedValue(strategy = GenerationType.AUTO)
var id: Long = 0
)
下面看到的 Spring MVC REST 控制器使用了建構函式注入,並且 Kotlin 中的預設可見性是 public,因此無需指定。當函式返回單個表示式時,可以省略花括號,並且主體在 = 符號之後指定。這更好,因為編譯器可以推斷出返回型別。
@RestController
class CustomerController (val repository:CustomerRepository) {
@GetMapping("/")
fun findAll() = repository.findAll()
@GetMapping("/{name}")
fun findByLastName(@PathVariable name:String)
= repository.findByLastName(name)
}
Spring Data 儲存庫不言自明。
interface CustomerRepository : CrudRepository<Customer, Long> {
fun findByLastName(name: String): List<Customer>
}
由於 Kotlin 支援頂級函式,您可以像這樣簡單地宣告您的應用程式:
@SpringBootApplication
class Application {
@Bean
fun init(repository: CustomerRepository) = CommandLineRunner {
repository.save(Customer("Jack", "Bauer"))
repository.save(Customer("Chloe", "O'Brian"))
repository.save(Customer("Kim", "Bauer"))
repository.save(Customer("David", "Palmer"))
repository.save(Customer("Michelle", "Dessler"))
}
}
fun main(args: Array<String>) {
SpringApplication.run(Application::class.java, *args)
}
您需要使用 kotlin-spring 外掛 來自動使 @Configuration 類以及其他一些 @Service 或 @Repository 成為 open,因為它們在 Spring 中不能是 final 的,這歸因於 CGLIB 代理的使用(Kotlin 中的類和方法預設是 final 的,沒有 open 修飾符)。使用 JDK 動態代理的 Bean 不需要 open 修飾符。
儘管 Spring Boot 和 Kotlin 配合得很好,但以下附加提示也值得了解。請參閱 此 issue 瞭解有關改進 Spring Boot 中 Kotlin 支援的更多詳細資訊。
與 Java 不同,Kotlin 目前不允許將陣列註解屬性指定為單個值(value 屬性除外),因此請注意,您必須編寫 @RequestMapping(method = arrayOf(RequestMethod.GET)) 或 @EnableAutoConfiguration(exclude = arrayOf(Foo::class))。
預計此行為將在即將釋出的 Kotlin 1.2 中得到改進(有關更多詳細資訊,請參閱此 Kotlin issue)。Spring Framework 4.3 的複合註解(如 @GetMapping 或 @PostMapping)也可以提供幫助。
我們之前已經看到了如何進行建構函式注入,因為這是推薦的方法(尤其是在 Kotlin 中)。如果您必須執行屬性注入,您將不得不使用延遲初始化屬性,因為通常,宣告為非可空型別的原始屬性必須在建構函式中初始化。
@RestController
class CustomerController {
@Autowired
lateinit var repository:CustomerRepository
// ...
}
在 Kotlin 中,$ 用於字串插值,因此在使用屬性佔位符時應對其進行轉義:@Value("\${some.property}")。作為替代,您也可以使用@ConfigurationProperties,有關更多詳細資訊,請參閱此Stack Overflow答案。
如果您使用 Jackson,您可能希望新增 com.fasterxml.jackson.module:jackson-module-kotlin 依賴項,以便它能夠處理沒有預設建構函式或使用 Kotlin 集合的資料類。Spring Framework 4.3+ 會自動註冊它。
最後一個提示,IntelliJ IDEA 中的 Java 轉 Kotlin 轉換器(選單 Code -> Convert Java file to Kotlin file)在您無法弄清楚如何在 Kotlin 中編寫某些內容時非常有用。因此,請不要猶豫,先用 Java 編寫一些內容,然後使用它來查詢 Kotlin 的對應項。此與 Java 的對比文件也可以提供一些幫助。
我們對您使用 Kotlin 開發 Spring 應用程式的反饋很感興趣。這篇博文只是一個介紹,還有很多內容可以討論,尤其是在使用 Spring Boot 和更具 Kotlin 風格的程式碼(如使用 Exposed SQL 庫)方面,敬請期待 **(更新:下一篇 Kotlin 博文現已釋出 在此)**……