Spring y Kotlin
Introducción
Kotlin es un lenguaje de programación de tipo estático, que se ejecuta en la JVM. JetBrains lo desarrolla desde 2010. Puede funcionar en un entorno nativo sin JVM, en un entorno JavaScript y en un entorno JVM. En este capítulo, solo abordaremos la versión del lenguaje que se ejecuta en una JVM. Del mismo modo, solo veremos algunos aspectos de este lenguaje porque se necesitaría un libro completo para describir íntegramente su integración con Spring. Tendremos una visión general de los nuevos conceptos aportados por al lenguaje.
JetBrains se creó en 2000 para hacer herramientas en varios lenguajes. La empresa JetBrains se distinguió por su editor IntelliJ IDEA y sus derivados (como PhpStorm para PHP) y recibió el premio Most Innovative Java Compagnie en 2012.
Los aspectos fundamentales de Kotlin son:
Aspecto |
Aspiración |
Concisión |
No hay código único para todos |
Expresividad |
Grandes ideas en pocas palabras |
Interoperabilidad |
Para soportar código existente |
Pragmatismo |
Atención a la vida real |
Kotlin toma ideas de Java, Groovy, Scala y Ceylon, simplificándolas tanto como sea posible.
Cada vez más proyectos usan Kotlin, incluidos los proyectos de Android, para los que ahora se soporta Kotlin.
Ya estábamos usando Java 8 y sus nuevas funcionalidades, pero deberíamos considerar la posibilidad de migrar a Kotlin. Este...
Características principales del lenguaje Kotlin
Tenemos clases, como en Java, pero estas clases son públicas por defecto. Veremos que es posible utilizar los plugins de Maven y Gradle para tener en cuenta este aspecto.
1. Los métodos y las funciones
He aquí un ejemplo de una función:
fun maxOf(a: Float, b: Float) = if (a > b) a else b
Vemos que:
-
el tipo tiene el sufijo,
-
hay una sintaxis corta para las funciones que caben en una línea,
-
el if devuelve un valor y, por lo tanto, se puede utilizar en una expresión,
-
todo está tipado estáticamente.
2. La inmutabilidad de los objetos
En Java, algunos objetos son inmutables, como las constantes y algunas colecciones, pero, en general, es muy posible modificar el contenido de un objeto pasado como argumento de un método y este intercambio de estados se vuelve muy complejo de gestionar. Una buena práctica es no modificar nunca un objeto pasado como argumento, sino devolver una copia modificada como con la clase String en Java. Algunos proyectos en Java usan la librería Immutable: (https://immutables.github.io/), pero esto sigue siendo un truco en Java y la inmutabilidad se puede evitar con reflexibilidad y las listas son vulnerables.
Los inmutables son thread-safe y resultan ideales para las claves de Map y de Set, se pueden almacenar en caché y la validación de los campos se realiza durante la creación del objeto (o su copia extendida).
El proyecto Lombok ya ofrece las val y var, que está cerca de lo que se hace en Kotlin. JEP 286 aborda este tema para Java: http://openjdk.java.net/jeps/286. JEP es el eje de todas las propuestas de mejora del JDK para OpenJDK.
En Kotlin, la inmutabilidad de los objetos, que es una garantía de buen funcionamiento, se gestiona a través del tipo val:
var x // objeto mutable
val y // Objeto inmutable
3. Los tipos
Hay una inferencia de tipos:
//Inferido
val y1 = "abc"
val y2 = 4
//Declarado implícitamente
val y3: List<String> = ArrayList()
val y4: Double = 3.14159
Hay adaptaciones inteligentes de tipo:
val obj = 2.5
if (obj is Double) {
println(obj.inc())
}...
Controlador Spring MVC, Spring Boot en Kotlin
Utilizar Spring Initializr en https://start.spring.io/ para crear una aplicación Maven Kotlin:
Ítem |
valor |
Group |
fr.eni.kotlin.spring5.mvc |
Artefact |
kotlin |
Name |
kotlin |
Description |
Ejemplo 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 |
Tabla 3. Argumentos.
Nombre de las dependencias |
Spring Web |
Mustache |
Spring Data JPA |
H2 Database |
Spring Boot DevTools |
Rest Repository HAL Browser |
Tabla 4. Dependencias.
Tenemos las dependencias:
Librería |
Utilidad |
kotlin-stdlib-jdk8 |
Variante Java 8 de la librería estándar Kotlin. |
kotlin-reflect |
La librería de reflexión de Kotlin. |
jackson-module-kotlin |
Soporte para serialización/deserialización de clases. |
1. Función principal
Tenemos la clase para lanzar nuestro programa:
KotlinAplicación:
@SpringBootApplication
class KotlinApplication
fun main(args: Array<String>) {
runApplication<KotlinApplication>(*args)
}
2. Prueba asociada a la función principal
He aquí hay una prueba de la clase del programa principal.
KotlinApplicationTests.kt:
@SpringBootTest
class KotlinApplicationTests {
@Test
fun contextLoads() {
}
}
Debe configurar la base de datos H2 en el archivo 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
Pasar el scope de h2 de runtime a compile en el pom.xml.
Añadir un perfil de ejecución:
fr-eni-kotlin-spring5-mvc/src/main/kotlin/fr/eni/kotlin/spring5/mvc/app/config/ProfileExecution.kt...
Los plugins
Los plugins Maven para la versión Spring de Java también están disponibles para Spring Kotlin. El plugin all-open se creó porque Spring necesita sobrecargar los métodos cglib para sus proxies. Kotlin declara sus clases y métodos finales de forma predeterminada, lo que no permite que Spring se sobrecargue. Por lo tanto, es necesario declarar sistemáticamente las API de los @Bean publicados a través del operador open o usar el plugin Kotlin Spring, que lo hace por usted.
Es posible usar el plugin all-open Maven o Gradle para hacer que las clases y los métodos sean automáticamente open (públicos).
En el código siguiente, sin el plugin Maven, necesitamos establecer open para especificar que la clase y el método son públicos, porque son privados por defecto con Kotlin, a diferencia de lo que ocurre con Java.
@SprinBootApplication
open class Application {
@Bean
open fun fonction1() = ...
}
con:
@SprinBootApplication
class Application {
@Bean
fun fonction1() = ...
}
Build Maven
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</
sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</
testSourceDirectory>
<plugins> ...
Puntos clave
-
Kotlin podría sustituir a Java y usar la JVM.
-
Spring ha trabajado mucho en la integración de Kotlin.
-
JetBrains, que hizo el excelente IntelliJ IDEA, ha creado un lenguaje muy potente.
-
Es posible convertir Java a Kotlin copiando/pegando en IntelliJ IDEA.