Spring et Kotlin
Introduction
Kotlin est un langage de programmation typé statiquement, qui s’exécute sur la JVM. Il a été développé par JetBrains depuis 2010. Il peut fonctionner dans un environnement en natif sans JVM, dans un environnement JavaScript et dans un environnement JVM. Nous n’abordons que la version du langage s’exécutant dans une JVM dans ce chapitre. De même, nous ne verrons que quelques aspects de ce langage, car il nous faudrait un livre entier pour le décrire entièrement avec son intégration avec Spring. Nous aurons une vision d’ensemble des nouveaux concepts amenés avec ce langage.
JetBrains fut créé en 2000 pour faire des outils sur plusieurs langages. La société JetBrains s’est distinguée avec son éditeur IntelliJ IDEA et ses dérivés (comme PhpStorm pour le PHP) et a reçu le "award de la Most Innovative Java Compagnie" en 2012.
Les aspects fondamentaux de Kotlin sont les suivants :
Aspect |
Volonté |
Concision |
Pas de code passe-partout |
Expressivité |
De grandes idées en peu de mots |
Interopérabilité |
Pour supporter le code existant |
Pragmatisme |
Préoccupation de la vie réelle |
Kotlin reprend des idées de Java, Groovy, Scala et Ceylon tout en les simplifiant au maximum.
De plus en plus de projets utilisent Kotlin, y compris des projets...
Caractéristiques principales du langage Kotlin
Nous avons des classes, comme en Java, mais ces classes sont publiques par défaut. Nous verrons qu’il est possible d’utiliser des plugins Maven et Gradle pour prendre en compte cet aspect.
1. Les méthodes et les fonctions
Voici un exemple de fonction :
fun maxOf(a: Float, b: Float) = if (a > b) a else b
Nous voyons que :
-
le type est suffixé,
-
il y a une syntaxe courte pour les fonctions qui tiennent sur une ligne,
-
le if renvoie une valeur et peut être donc utilisé dans une expression,
-
tout est typé statiquement.
2. L’immutabilité des objets
En Java, certains objets sont immutables comme les constantes et certaines collections, mais dans l’ensemble il est tout à fait possible de modifier le contenu d’un objet passé en paramètre d’une méthode et ce partage des états devient très complexe à gérer. Une bonne pratique consiste à ne jamais modifier un objet passé en paramètre, mais de plutôt en renvoyer une copie modifiée comme avec la classe String en Java. Certains projets en Java utilisent la librairie Immutable : (https://immutables.github.io/), mais cela reste un artifice en Java et l’immutabilité reste contournable avec la réflexibilité et les listes sont vulnérables.
Les immutables sont thread-safe, ils sont idéaux pour des clés de Map et de Set, ils peuvent être mis dans un cache, la validation des champs se fait à la création de l’objet (ou de sa copie augmentée).
Le projet Lombok propose déjà les val et var, qui est proche de ce qui est fait en Kotlin. la JEP 286 aborde ce sujet pour Java : http://openjdk.java.net/jeps/286. Le JEP est l’index de toutes les propositions d’amélioration du JDK pour l’OpenJDK.
En Kotlin, l’immutabilité des objets qui est un gage de bon fonctionnement est gérée via le type val :
var x // Objet mutable
val y // Objet immutable
3. Les types
Il existe une inférence de type :
//Inféré
val y1 = "abc"
val y2 = 4
//Déclaré implicitement
val y3: List<String> = ArrayList()...
Contrôleur Spring MVC, Spring Boot en Kotlin
Utiliser le Spring Initializr sur https://start.spring.io/ pour générer une application Maven Kotlin :
Item |
valeur |
Group |
fr.eni.kotlin.spring5.mvc |
Artefact |
kotlin |
Name |
kotlin |
Description |
Exemple Spring 5 Kotlin Spring Boot Spring MVC |
Package Name |
fr.eni.kotlin.spring5.mvc.app |
Packaging |
jar |
Java Version |
17 |
Spring Boot |
2.6.7 |
Table 3. Paramètres.
Nom des dépendances |
Spring Web |
Mustache |
Spring Data JPA |
H2 Database |
Spring Boot DevTools |
Rest Repository HAL Browser |
Table 4. Dépendances.
Nous avons les dépendances :
Librairie |
Utilité |
kotlin-stdlib-jdk8 |
Variante Java 8 de la bibliothèque standard Kotlin. |
kotlin-reflect |
La bibliothèque de réflexion Kotlin. |
jackson-module-kotlin |
Prise en charge de la sérialisation/désérialisation des classes. |
1. Fonction principale
Nous avons la classe pour lancer notre programme :
KotlinApplication :
@SpringBootApplication
class KotlinApplication
fun main(args: Array<String>) {
runApplication<KotlinApplication>(*args)
}
2. Test associé à la fonction principale
Voici un test de la classe du programme principal.
KotlinApplicationTests.kt :
@SpringBootTest
class KotlinApplicationTests {
@Test
fun contextLoads() {
}
}
Il faut configurer la base H2 dans le fichier application.properties :
spring.datasource.url = jdbc:h2:~/test
spring.datasource.username = sa
spring.datasource.password =
spring.jpa.properties.hibernate.dialect =
org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto = update
Passer le scope de h2 de runtime à compile dans le pom.xml.
Ajouter un profil d’exécution :
fr-eni-kotlin-spring5-mvc/src/main/kotlin/fr/eni/kotlin/spring5/mvc/app/config/ProfileExecution.kt...
Les plugins
Les plugins Maven pour Spring version Java sont aussi disponibles pour Spring Kotlin. Le plugin all-open a été fait car Spring a besoin de surcharger les méthodes cglib pour ses proxys. Kotlin déclare ses classes et ses méthodes finales par défaut, ce qui ne permet pas à Spring de surcharger. Il faut donc systématiquement déclarer les API des @Bean publiques via l’opérateur open ou utiliser le plugin Kotlin Spring qui le fait alors pour vous.
Il est possible d’utiliser le plugin all-open Maven ou Gradle pour rendre automatiquement open (publique) les classes et les méthodes :
Dans le code suivant, sans le plugin Maven, nous devons mettre open pour spécifier que la classe et la méthode sont publiques car elles sont privées par défaut avec Kotlin, contrairement à ce qui se passe avec Java.
@SprinBootApplication
open class Application {
@Bean
open fun fonction1() = ...
}
avec :
@SprinBootApplication
class Application {
@Bean
fun fonction1() = ...
}
Build Maven
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</
sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</
testSourceDirectory> ...
Points clés
-
Kotlin pourrait remplacer Java et utiliser la JVM.
-
Spring a énormément travaillé sur l’intégration de Kotlin.
-
JetBrains qui fait l’excellent IntelliJ IDEA a créé un langage très puissant.
-
Il est possible de convertir du Java en Kotlin via un copier/coller dans IntelliJ IDEA.