Une histoire sur un projet Spring Boot écrit en Java qui prend en charge Kotlin

Contexte

Les ingénieurs de l'équipe NOREL sont en train de moderniser la technologie utilisée, et il y a eu un discours disant que "je veux quand même écrire un système écrit en Java / Spring Boot à Kotlin", donc je vais procéder à la correspondance pour qu'il puisse être développé dans Kotlin. Je suis.

Je vois souvent des articles comme commencer par Kotlin (Gradle) depuis le début, mais je n'ai pas trouvé beaucoup d'articles qui correspondent à Kotlin (Maven) alors qu'il était écrit en Java, alors j'ai essayé de m'en occuper.

Environnement existant

Fondamentalement, Spring Boot implémente uniquement l'API REST.

Politique de support de Kotlin

De plus, ce travail a été effectué sur IntelliJ.

Travaux de migration

Paramètres pom.xml

pom.xml


  <properties>
...
     <java.version>1.8</java.version>
+    <kotlin.version>1.2.10</kotlin.version>
+    <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
  </properties>

pom.xml


  <dependencies>
・ ・ ・
+    <dependency>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-stdlib</artifactId>
+      <version>${kotlin.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-reflect</artifactId>
+      <version>${kotlin.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-test</artifactId>
+      <version>${kotlin.version}</version>
+      <scope>test</scope>
+    </dependency>
  </dependencies>

--Construire les paramètres

À l'origine, je n'utilisais pas maven-compiler-plugin, mais chaque paquet est prêt pour le développement en Java et Kotlin.

J'utilise maven-compiler-plugin pour séparer par.

De plus, spring est défini comme compilerPlugins afin que diverses annotations utilisées dans Spring puissent être utilisées. Comme mentionné dans la documentation, la définition d'un plug-in à ressort semble éliminer le besoin de définir tout-ouvert.

pom.xml


  <build>
     <finalName>${project.name}</finalName>
-    <sourceDirectory>src/main/java</sourceDirectory>
-    <testSourceDirectory>src/test/java</testSourceDirectory>
    <resources>
      <resource>
        <directory>${resources.directory}</directory>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
     </resources>
     <testResources>
       <testResource>
         <directory>src/test/resources</directory>
       </testResource>
     </testResources>
     <plugins>
       <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
         <configuration>
           <executable>true</executable>
         </configuration>
       </plugin>
+      <plugin>
+        <artifactId>kotlin-maven-plugin</artifactId>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <version>${kotlin.version}</version>
+        <configuration>
+          <compilerPlugins>
+            <plugin>spring</plugin>
+          </compilerPlugins>
+        </configuration>
+        <executions>
+          <execution>
+            <id>compile</id>
+            <goals> <goal>compile</goal> </goals>
+            <configuration>
+              <sourceDirs>
+                <sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
+                <sourceDir>${project.basedir}/src/main/java</sourceDir>
+              </sourceDirs>
+            </configuration>
+          </execution>
+          <execution>
+            <id>test-compile</id>
+            <goals> <goal>test-compile</goal> </goals>
+            <configuration>
+              <sourceDirs>
+                <sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
+                <sourceDir>${project.basedir}/src/test/java</sourceDir>
+              </sourceDirs>
+            </configuration>
+          </execution>
+        </executions>
+        <dependencies>
+          <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-maven-allopen</artifactId>
+            <version>${kotlin.version}</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.5.1</version>
+        <executions>
+          <!-- Replacing default-compile as it is treated specially by maven -->
+          <execution>
+            <id>default-compile</id>
+            <phase>none</phase>
+          </execution>
+          <!-- Replacing default-testCompile as it is treated specially by maven -->
+          <execution>
+            <id>default-testCompile</id>
+            <phase>none</phase>
+          </execution>
+          <execution>
+            <id>java-compile</id>
+            <phase>compile</phase>
+            <goals> <goal>compile</goal> </goals>
+          </execution>
+          <execution>
+            <id>java-test-compile</id>
+            <phase>test-compile</phase>
+            <goals> <goal>testCompile</goal> </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
  </build>

Vous êtes maintenant prêt à écrire Kotlin sur IntelliJ.

Prise en charge de STS (Eclipse)

Quand j'ai demandé aux membres qui utilisent habituellement STS pour la correspondance jusqu'à présent, cela n'a pas bien fonctionné et j'en étais un peu accro, alors je vais également décrire comment gérer STS.

--Installez le Kotlin Plugin for Eclipse depuis le marché Eclipse.

buildPath.png

Dans la figure ci-dessous, il ne peut pas être sélectionné car il a déjà été ajouté Kotlin Nature, mais il peut être sélectionné avant l'exécution.

AddKotlinNature.png

Maintenant, il se compile sur STS et vous pouvez développer sur Kotlin.

Ecrire Kotlin

Convertir du code Java en code Kotlin

Comme la fonction de conversion d'IntelliJ est excellente, je l'ai essentiellement convertie avec IntelliJ. C'est effrayant de les assembler tous à la fois, alors j'ai converti un ou plusieurs codes à la fois.

Sélectionnez le code que vous souhaitez convertir et convertissez-le en code Kotlin avec Code> Convertir le fichier Java en fichier Kotlin.

ConvertToKotlin.png

De plus, puisque le paquet est toujours sous src / main / java, déplacez-le sous le même paquet sous src / main / kotlin. Cela permet également de bien refactoriser avec Refactor> Move ... dans IntelliJ.

DI (câblé automatiquement, etc.)

Par exemple, le code ci-dessous

@Service
public class HogeService {
    @Autowired
    private HogeRepository hogeRepository;
}

Dans Kotlin, il peut être déclaré avec late init, mais cette fois, il est défini avec constructor injection.

@Service
class HogeService(
    private val hogeRepository: HogeRepository
) {
}

Autour de Lombok

Lors de l'utilisation de Lombok, j'ai parfois une erreur de compilation lors de la conversion vers Kotlin.

Fondamentalement, la classe qui se convertit en Kotlin et la classe référencée à partir de Kotlin sont résolues par Delombok.

Utilisez le plug-in lombok d'IntelliJ. Il supprime la conversion Lombok de Refactor> Delombok.

Delombok.png

Vous pouvez omettre la déclaration du journal et écrire du code qui génère soudainement des journaux. Si vous utilisez Kotlin, le code suivant ne pourra pas résoudre la variable de journal et entraînera une erreur de compilation.

@Service
@Slf4j
public class HogeService {
    public void hoge() {
        log.info("hoge");
    }
}

Dans kotlin, il peut être utilisé en initialisant le logger avec objet compagnon.

@Service
class HogeService {
    companion object {
        private val log = LoggerFactory.getLogger(HogeService::class.java)
    }
}

Certaines personnes ont essayé la méthode DI avec annotations, alors j'aimerais envisager de la rendre plus facile. http://saiya-moebius.hatenablog.com/entry/2017/11/08/033932

J'ai lu le code Java Lombokized suivant de Kotlin, et quand j'essaye d'obtenir le hoge, il dit qu'il est privé et non accessible. Dans ce cas, comme décrit ci-dessus, il a été converti en Delombok. (Si tout devient Kotlin, vous n'êtes pas obligé d'utiliser Lombok en premier lieu ...)

@Entity
@Data
@EqualsAndHashCode(callSuper = false)
@ToString(callSuper = true)
public class Hoge extends AbstractEntity {
	@Column(name = "hoge")
	private String hoge;
}

À propos du futur

Pour le moment, un certain code est maintenant Kotlinized et fonctionne. Cependant, j'ai eu des problèmes à plusieurs reprises pendant que j'écrivais le code, il est donc possible que je continue à avoir des problèmes. Je pense que je devrais ajouter de plus en plus comment y faire face.

Recommended Posts

Une histoire sur un projet Spring Boot écrit en Java qui prend en charge Kotlin
Conseils Java - Créez un projet Spring Boot avec Gradle
Créer un projet Java Spring Boot avec IntelliJ
Une histoire sur le JDK à l'ère de Java 11
Exécuter un projet Spring Boot avec VS Code
Comment créer un projet Spring Boot dans IntelliJ
Une histoire sur une BeanNotOfRequiredTypeException qui s'est produite après l'application d'AOP au printemps
Un mémo qui a touché Spring Boot
Comparez Hello, world! Avec Spring Boot avec Java, Kotlin et Groovy
A propos du renvoi d'une référence dans un Java Getter
Lancer un (ancien) projet Spring Boot avec IntelliJ
Injection de dépendances Spring à l'aide de Java, Kotlin
[Création] Un mémorandum sur le codage en Java
Créez un projet Spring Boot avec intellij et quittez immédiatement après le lancement
Les champs auto-câblés dans une classe qui hérite de TextWebSocketHandler dans Spring Boot deviennent NULL
Déployer automatiquement des applications Web développées en Java à l'aide de Jenkins [Spring Boot App Edition]
L'histoire de la rencontre d'un débordement arithmétique qui ne devrait pas être rencontré dans Ruby
Une histoire sur la prise en charge de Java 11 pour les services Web
Une histoire sur la création d'un Builder qui hérite du Builder
Histoire d'essayer de faire fonctionner le fichier JAVA
Comment ajouter un chemin de classe dans Spring Boot
Un fichier bat qui utilise Java dans Windows
Vérifiez avec Java / Kotlin que les fichiers ne peuvent pas être écrits en UAC sous Windows
Afficher la tâche Gradle dans le projet Spring Boot
L'histoire du port devenant inutilisable dans l'exemple de programme Spring Boot
Jusqu'à ce que vous créiez un projet Spring Boot dans Intellij et que vous le transmettiez à Github
Ecrire une classe qui peut être ordonnée en Java Un petit mémo standard
Ecrire une classe en Kotlin et l'appeler en Java
[Spring Boot] Comment créer un projet (pour les débutants)
Essayez gRPC dans le projet Spring Boot et Spring Cloud (Mac OS)
Une histoire sur le développement de ROS appelé rosjava avec java
Appeler un programme écrit en Swift depuis Processing (Java)
L'histoire que .java est également construite dans Unity 2018
Une bibliothèque qui réalise des chaînes multilignes en chaîne multiligne Java
Découvrez les spécifications tout en raccourcissant FizzBuzz écrit en Java
[Java / Kotlin] Traitement d'échappement (désinfection) pour HTML5 avec unbescape [Spring Boot]
Accélérez les tests des validateurs qui nécessitent DI dans Spring Boot
Une histoire remplie des bases de Spring Boot (résolu)
Exemple d'application Web qui gère plusieurs bases de données avec Spring Boot 1.5
Comment appeler et utiliser l'API en Java (Spring Boot)
[Java] Un article sur IntelliJ IDEA enseignant la méthode putIfAbsent de Map
Une histoire sur la prise en charge de la réplication par les applications Spring + Hibernate + MySQL
[MQTT / Java] Implémentation d'une classe qui fait Pub / Sub de MQTT en Java
Présentation de Spring Boot2, un framework Java pour le développement Web (pour les débutants)
Une histoire de malentendu sur l'utilisation du scanner Java (mémo)
[Java] Exemple de projet de développement d'applications Web avec Spring Boot
Une histoire qui m'a fait regretter quand une "NotReadablePropertyException" s'est produite pendant le développement de l'application Spring Boot.
Avec [AWS] CodeStar, vous pouvez créer un projet Spring (Java) s'exécutant sur Lambda en seulement 3 minutes! !!
J'ai créé un exemple d'application Selenium qui prend en charge plusieurs navigateurs (Chrome, IE, Firefox) qui s'exécute sur Java.
Remarques sur Java GC
Définir le paramètre contextuel dans Spring Boot
Multi-projets Spring Boot 2 avec Gradle
[Java] Thymeleaf Basic (Spring Boot)
Rechercher un sous-ensemble en Java
[Java] Obtenir KClass en Java [Kotlin]
Application Java CICS-Run - (4) Application Spring Boot
Changements majeurs dans Spring Boot 1.5
NoHttpResponseException dans Spring Boot + WireMock
[Java] [Spring] Spring Boot 1.4-> 1.2 Note de rétrogradation