Spring Boot dan Kotlin

1. Gambaran keseluruhan

Pengumuman besar dibuat pada bulan Januari dalam ekosistem Spring: Sokongan Kotlin akan datang ke Spring Framework 5 . Ini bermakna Spring Boot 2.x akan mendapat sokongan kelas pertama untuk Kotlin.

Ini tentu saja tidak dijangka, kerana pasukan di Pivotal terkenal dengan penerimaan bahasa JVM seperti Scala dan Groovy.

Mari bina aplikasi Kotlin menggunakan aplikasi Spring Boot 2.x!

2. Persediaan

2.1. Persekitaran

Kotlin menyokong pembangunan di IntelliJ, Eclipse, dan pada baris perintah. Ikuti arahan untuk mengatur persekitaran anda, berdasarkan pilihan anda.

2.2. Persediaan

Pertama, mari buat projek Spring Boot 2 dan ubah POM untuk mengandungi entri yang menentukan versi Java dan Kotlin dengan pergantungan:

 org.jetbrains.kotlin kotlin-stdlib-jre8 1.2.71   org.jetbrains.kotlin kotlin-reflect 1.2.71   com.fasterxml.jackson.module jackson-module-kotlin 2.9.9 

Perhatikan bahawa kami menentukan lokasi fail untuk sumber Kotlin dan fail ujian kami:

${project.basedir}/src/main/kotlin ${project.basedir}/src/test/kotlin

Sekiranya fail Kotlin kami berada di lokasi yang berbeza, anda perlu mengubah entri ini di POM.

Untuk menyusun modul dan sumber Kotlin, kita perlu menggunakan kotlin-maven-plugin:

 kotlin-maven-plugin org.jetbrains.kotlin 1.1.2   spring  1.8    compile compile  compile    test-compile test-compile  test-compile      org.jetbrains.kotlin kotlin-maven-allopen 1.1.2   

Baiklah, sekarang kita mempunyai semua yang kita perlukan untuk membina aplikasi Kotlin kita. Sebagai rujukan: anda boleh mendapatkan versi terbaru Maven Central (spring-boot-starter-web, kotlin-stdlib-jre8, kotlin-reflect, jackson-module-kotlin, test).

Seterusnya, mari sediakan konteks aplikasi kami.

3. Konteks Aplikasi

Mari masuk ke dalam beberapa kod Kotlin dan tulis konteks aplikasi Spring Boot yang sudah biasa kita:

@SpringBootApplication class KotlinDemoApplication fun main(args: Array) { SpringApplication.run(KotlinDemoApplication::class.java, *args) }

Kami melihat anotasi @SpringBootApplication kami yang biasa . Ini adalah anotasi yang sama yang akan kita gunakan dalam kelas Java.

Di bawah ini kami mempunyai definisi kelas untuk kelas KotlinDemoApplication kami . Di Kotlin, ruang lingkup lalai untuk kelas adalah umum sehingga kita dapat menghilangkannya. Selain itu, jika kelas tidak mempunyai pemboleh ubah dan tidak ada fungsi, ia dapat dinyatakan tanpa pendakap keriting. Oleh itu, pada dasarnya, kita baru sahaja menentukan kelas.

Melangkah ke kaedah. Ini adalah kaedah titik masuk Java standard, di Java: public static void main (String [] args).

Sekali lagi, kaedah atau fungsi terbuka secara umum, jadi kami tidak perlu menyatakannya di sini. Selain itu, fungsi yang tidak mengembalikan apa-apa tidak perlu menentukan jenis pengembalian yang tidak sah.

Dan akhirnya, sebarang fungsi yang ditentukan di luar badan kelas secara automatik statik . Ini menjadikan fungsi ini layak untuk pelaksanaan permulaan.

Sekarang mari jalankan aplikasi kita dari direktori root menggunakan mvn spring-boot: run . Aplikasi harus dimulakan, dan kita harus melihat aplikasi kita berjalan di port 8080.

Seterusnya, mari kita membina pengawal.

4. Pengawal

Mari lihat menambahkan pengawal ke perkhidmatan kami:

@RestController class HelloController { @GetMapping("/hello") fun helloKotlin(): String { return "hello world" } }

Tidak terlalu berbeza dengan pengawal Spring standard tetapi pastinya kurang kod. Mari tambah kelas ujian dan kes untuk pengawal ini untuk mengesahkan kerja kami:

@RunWith(SpringRunner::class) @SpringBootTest(classes = arrayOf(KotlinDemoApplication::class), webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class KotlinDemoApplicationTests { @Autowired lateinit var testRestTemplate: TestRestTemplate @Test fun whenCalled_shouldReturnHello() { val result = testRestTemplate // ... .getForEntity("/hello", String::class.java) assertNotNull(result) assertEquals(result?.statusCode, HttpStatus.OK) assertEquals(result?.body, "hello world") } }

Ujian ini menunjukkan salah satu ciri Kotlin yang sangat hebat - keselamatan batal! Pemboleh ubah Kotlin yang boleh menjadi nol mesti dinyatakan menggunakan '?'. Penyusun kemudian mengetahui bahawa pengekodan defensif diperlukan sebelum mengakses harta itu.

Dalam ujian kami, TestRestTemplate didefinisikan sebagai jenis nullable , dan setiap kali kita mengaksesnya, kami melakukannya menggunakan operator penggabungan null "?." - yang akan mengembalikan null jika objek yang disebut adalah null.

Ini menjelaskan penggunaan nol dalam program dan memaksa pembangun menulis kod selamat ketika bekerja dengannya.

Seterusnya, mari tambahkan perkhidmatan dan gabungkan dengan pengawal kami.

5. Perkhidmatan

Seperti yang anda boleh sangka sekarang, perkhidmatan kami akan menjadi sangat mudah untuk ditambahkan ke dalam projek kami. Mari buat sekarang:

@Service class HelloService { fun getHello(): String { return "hello service" } }

Perkhidmatan yang cukup sederhana di sini dengan satu fungsi mengembalikan String. Seterusnya, mari masukkan perkhidmatan kami ke pengawal dan gunakannya untuk mengembalikan nilai:

@RestController class HelloController(val helloService: HelloService) { // ... @GetMapping("/hello-service") fun helloKotlinService(): String { return helloService.getHello() } }

Ahh, itu kelihatan bagus! Di Kotlin pembina utama boleh didefinisikan sejajar dengan perisytiharan kelas. Kami telah membuang anotasi @Autowired dari pembangun kami kerana tidak wajib sejak beberapa waktu lalu.

Parameter tersebut secara automatik ditukar menjadi medan di kelas. Kotlin mereka dipanggil harta tanah. Tidak ada penentu atau penentu yang ditentukan; mereka dibuat secara automatik. Anda tentu saja boleh mengatasi lalai ini jika anda mahu.

Di Kotlin, sifat dalam kelas dan pemboleh ubah dalam fungsi dapat didefinisikan menggunakan var atau val . Var menunjukkan harta yang boleh berubah, dan val menunjukkan yang terakhir. Ini membolehkan pengkompil memeriksa akses haram. Oleh kerana HelloService kami adalah singleton, kami memasangnya sebagai val untuk mengelakkan mutasi.

Seterusnya, mari kita tambahkan ujian untuk kaedah pengawal ini:

@Test fun whenCalled_shouldReturnHelloService() { var result = testRestTemplate // ... .getForEntity("/hello-service", String::class.java) assertNotNull(result) assertEquals(result?.statusCode, HttpStatus.OK) assertEquals(result?.body, "hello service") }

Terakhir, mari kita lihat bagaimana rupa POJO di Kotlin.

6. Kelas Data Kotlin

Di Java, kami mewakili objek data dengan objek Java lama biasa, POJO. Di Kotlin kami mempunyai sesuatu yang membolehkan kami mengekspresikan objek jenis ini dengan lebih ringkas - kelas data.

Mari tulis objek data untuk dikembalikan dalam pengawal kami:

data class HelloDto(val greeting: String)

Itu bukan muslihat. Saya tidak menghilangkan apa-apa dari kelas kami. Dengan pengubah data, kami mendapat banyak faedah. Kata kunci ini secara automatik membuat pasangan kod sama / hash , fungsi toString , dan fungsi salin. Semua itu dari 53 watak satu pelapik!

Sekarang mari kita tambahkan kaedah untuk mengembalikan kelas data baru kami:

// ... @GetMapping("/hello-dto") fun helloDto(): HelloDto { return HelloDto("Hello from the dto") }

Pengubah data tidak menambah konstruktor lalai, yang penting untuk perpustakaan tertentu seperti Jackson. Untuk menyokong kelas jenis ini, kami telah menambahkan jackson-module-kotlin ke fail POM kami untuk menyokong marshaling. Ini dilakukan semasa bahagian 2, dan anda dapat melihat kebergantungan di sana.

Akhirnya, mari kita tambahkan ujian untuk fungsi pengawal ini:

@Test fun whenCalled_shoudlReturnJSON() { val result = testRestTemplate // ... .getForEntity("/hello-dto", HelloDto::class.java) assertNotNull(result) assertEquals(result?.statusCode, HttpStatus.OK) assertEquals(result?.body, HelloDto("Hello from the dto")) }

7. Kesimpulannya

Dalam artikel ini, kami melihat sokongan Kotlin di Spring Boot 2.x. Kami melihat dari contoh bahawa Kotlin dapat mempermudah dan meningkatkan aplikasi kami dengan memaksa kami menulis kod yang lebih pendek dan lebih selamat.

Kotlin juga menyokong beberapa ciri luar biasa seperti kelas data, peluasan kelas, dan sepenuhnya serasi dengan kod Java yang ada. Ini bermakna anda boleh menulis kod Kotlin dan memanggilnya dari kelas Java anda dan sebaliknya. Sebagai tambahan, Kotlin dibangun dari bawah ke atas untuk mendapat sokongan hebat dalam IDE, dan memang demikian.

Terdapat banyak alasan untuk mencuba Kotlin, dan dengan Google dan Spring menyokongnya, sekarang adalah masa untuk memeriksanya. Beritahu kami apa yang anda memutuskan untuk membuatnya menggunakannya!

Selalu, anda boleh mendapatkan kod sumber di GitHub.