Весняний черевик і Котлін

1. Огляд

Велике оголошення було зроблено ще в січні в екосистемі Spring: підтримка Kotlin надходить до Spring Framework 5 . Це означає, що Spring Boot 2.x матиме першокласну підтримку Kotlin.

Це, звичайно, не несподівано, оскільки команда Pivotal відома тим, що приймає такі мови JVM, як Scala та Groovy.

Давайте створимо додаток Kotlin за допомогою програми Spring Boot 2.x!

2. Налаштування

2.1. Навколишнє середовище

Kotlin підтримує розробку в IntelliJ, Eclipse та в командному рядку. Дотримуйтесь інструкцій, щоб налаштувати своє середовище, виходячи з ваших уподобань.

2.2. Налаштування

Спочатку давайте створимо проект Spring Boot 2 та модифікуємо POM, щоб містити записи, що вказують версії Java та Kotlin із залежностями:

 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 

Зверніть увагу, що ми вказуємо розташування файлів для наших вихідних та тестових файлів Kotlin:

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

Якщо наші файли Kotlin знаходяться в різних місцях, вам доведеться змінити ці записи в POM.

Для компіляції модулів і джерел Kotlin нам потрібно використовувати 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   

Добре, тепер у нас є все необхідне для створення нашого додатку Kotlin. Для довідки: ви можете знайти найновіші версії Maven Central (spring-boot-starter-web, kotlin-stdlib-jre8, kotlin-reflect, jackson-module-kotlin, test).

Далі, давайте налаштуємо наш контекст програми.

3. Контекст програми

Давайте перейдемо до коду Kotlin і напишемо наш звичний контекст програми Spring Boot:

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

Ми бачимо нашу звичну анотацію @SpringBootApplication . Це та сама анотація, яку ми використовували б у класі Java.

Нижче ми маємо визначення класу для нашого класу KotlinDemoApplication . У Kotlin область за замовчуванням для класів є загальнодоступною, тому ми можемо це пропустити. Крім того, якщо клас не має змінних і функцій, його можна оголосити без фігурних дужок. Отже, по суті, ми щойно визначили клас.

Переходимо до методу. Це стандартний метод точки входу Java на Java: public static void main (String [] args).

Знову ж таки, методи або функції є загальнодоступними за замовчуванням, тому ми не повинні заявляти про це тут. Крім того, функції, які нічого не повертають, не повинні вказувати тип повернення порожнечі.

І нарешті, будь-яка функція, визначена поза тілом класу, автоматично є статичною . Це робить цю функцію придатною для запуску.

А тепер давайте запустимо наш додаток із кореневого каталогу за допомогою mvn spring-boot: run . Додаток має запуститися, і ми побачимо, що наша програма працює на порту 8080.

Далі, давайте побудуємо контролер.

4. Контролер

Давайте поглянемо на додавання контролера до нашого сервісу:

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

Не сильно відрізняється від стандартного контролера Spring, але, звичайно, менше коду. Давайте додамо тестовий клас і кейс для цього контролера для перевірки нашої роботи:

@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") } }

Цей тест демонструє одну з дуже потужних функцій Котліна - нульову безпеку! Змінні Kotlin, які можуть бути нульовими, повинні бути оголошені за допомогою '?'. Тоді компілятор знає, що перед доступом до цього властивості потрібно захисне кодування.

У нашому тесті TestRestTemplate визначається як типовий тип, і кожен раз, коли ми отримуємо до нього доступ, ми робимо це, використовуючи нульовий оператор злиття “?”. - який поверне значення null, якщо викликаний об'єкт має значення null.

Це уточнює використання нульових значень у програмі та змушує розробників писати безпечний код під час роботи з ними.

Далі, давайте додамо послугу та інтегруємо її в наш контролер.

5. Обслуговування

Як ви вже зараз можете здогадатися, наш сервіс буде дуже легко додати до нашого проекту. Давайте зробимо це зараз:

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

Тут досить простий сервіс з однією функцією, що повертає рядок. Далі, давайте підключимо наш сервіс до контролера і використаємо його для повернення значення:

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

Ааа, це виглядає приємно! У Kotlin головний конструктор можна визначити вбудовано з оголошенням класу. Ми опустили анотацію @Autowired від нашого конструктора, оскільки вона не є обов'язковою з певного часу.

Ці параметри автоматично перетворюються на поля класу. Котлін їх називають властивостями. Не визначено жодного геттера чи сеттера; вони створюються автоматично. Звичайно, ви можете замінити ці за замовчуванням, якщо хочете.

In Kotlin, properties in classes and variables in functions can be defined using var or val. Var indicates a mutable property, and val indicates a final one. This allows the compiler to check for illegal access. Since our HelloService is a singleton, we wire it up as a val to prevent mutation.

Next, let's add a test for this controller method:

@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") }

Lastly, let's look at what a POJO looks like in Kotlin.

6. Kotlin Data Class

In Java, we represent data objects with plain old Java objects, the POJO. In Kotlin we have something that lets us express this type of object more concisely – a data class.

Let's write a data object to return in our controller:

data class HelloDto(val greeting: String)

That was no trick. I'm not omitting anything from our class. With the data modifier, we get a lot of benefits. This keyword automatically creates an equals/hashcode pair, a toString function, and a copy function. All that from a 53 character one-liner!

Now let's add a method to return our new data class:

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

The data modifier does not add a default constructor, which is important for certain libraries like Jackson. To support this type of class we have added the jackson-module-kotlin to our POM file to support marshaling. This was done during section 2, and you can see the dependency there.

Finally, let's add a test for this controller function:

@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. Conclusion

У цій статті ми розглянули підтримку Kotlin у Spring Boot 2.x. На прикладах ми побачили, що Котлін може спростити та вдосконалити наші програми, змусивши нас писати коротший та безпечніший код.

Kotlin також підтримує деякі дивовижні функції, такі як клас даних, розширення класу, і повністю сумісний з існуючим кодом Java. Це означає, що ви можете писати код Kotlin і викликати його зі своїх класів Java і навпаки. Крім того, Kotlin був побудований з нуля, щоб мати фантастичну підтримку в IDE, і він це робить.

Є багато причин спробувати Котлін, і завдяки підтримці Google та Spring зараз саме час перевірити це. Повідомте нас, що ви вирішили побудувати, використовуючи його!

Завжди ви можете знайти вихідний код на GitHub.