Spring Boot en Kotlin

1. Overzicht

In januari werd een grote aankondiging gedaan in het lente-ecosysteem: Kotlin-ondersteuning komt naar Spring Framework 5. Dit betekent dat Spring Boot 2.x eersteklas ondersteuning krijgt voor Kotlin.

Dit is natuurlijk niet onverwacht, want het team van Pivotal staat bekend om de acceptatie van JVM-talen zoals Scala en Groovy.

Laten we een Kotlin-app bouwen met Spring Boot-app 2.x!

2. Installatie

2.1. Milieu

Kotlin ondersteunt ontwikkeling in IntelliJ, Eclipse en op de opdrachtregel. Volg de instructies om uw omgeving in te stellen op basis van uw voorkeuren.

2.2. Opstelling

Laten we eerst een Spring Boot 2-project maken en de POM aanpassen om items te bevatten die de versies van Java en Kotlin specificeren met de afhankelijkheden:

 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 

Houd er rekening mee dat we bestandslocaties specificeren voor onze Kotlin-bron- en testbestanden:

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

Als onze Kotlin-bestanden zich op verschillende locaties bevinden, moet u deze vermeldingen in de POM wijzigen.

Om Kotlin-modules en -bronnen te compileren, moeten we kotlin-maven-plugin:

 kotlin-maven-plugin org.jetbrains.kotlin 1.1.2 lente 1.8 compileren compileren compileren test-compileren test-compileren test-compileren org.jetbrains.kotlin kotlin-maven-allopen 1.1.2 

Oké, nu hebben we alles wat we nodig hebben om onze Kotlin-applicatie te bouwen. Ter referentie: u vindt de laatste versies van Maven Central (spring-boot-starter-web, kotlin-stdlib-jre8, kotlin-reflect, jackson-module-kotlin, test).

Laten we vervolgens onze toepassingscontext instellen.

3. Applicatiecontext

Laten we wat Kotlin-code bekijken en onze vertrouwde Spring Boot-toepassingscontext schrijven:

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

We zien onze vertrouwde @SpringBootApplication annotatie. Dit is dezelfde annotatie die we zouden gebruiken in een Java-klasse.

Daaronder hebben we een klassendefinitie voor onze KotlinDemoApplication klasse. In Kotlin is het standaardbereik voor klassen openbaar, zodat we dat kunnen weglaten. Als een klasse geen variabelen en geen functies heeft, kan deze bovendien zonder accolades worden gedeclareerd. Dus in wezen hebben we zojuist een klasse gedefinieerd.

Verder naar de methode. Dit is de standaard Java-toegangspuntmethode in Java: public static void main (String [] args).

Nogmaals, methoden of functies zijn standaard openbaar, dus we hoeven dat hier niet aan te geven. Bovendien, functies die niets retourneren, hoeven geen ongeldig retourtype te specificeren.

En tenslotte, elke functie die buiten de body van een klasse is gedefinieerd, is automatisch statisch. Hierdoor komt deze functie in aanmerking voor opstarten.

Laten we nu onze applicatie starten vanuit de hoofdmap met mvn spring-boot: run. De applicatie zou moeten starten en we zouden onze applicatie op poort 8080 moeten zien draaien.

Laten we vervolgens een controller bouwen.

4. Verantwoordelijke

Laten we eens kijken naar het toevoegen van een controller aan onze service:

@RestController klasse HelloController {@GetMapping ("/ hallo") plezier helloKotlin (): String {retourneer "hallo wereld"}}

Niet veel anders dan een standaard Spring controller maar zeker minder code. Laten we een testklasse en case toevoegen voor deze controller om ons werk te valideren:

@RunWith (SpringRunner :: class) @SpringBootTest (classes = arrayOf (KotlinDemoApplication :: class), webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class KotlinDemoApplicationTests {@Autowired lateinit var testRestTem-resultaat wanneerCalledTemoApplicationTests {@Autowired lateinit var testRestTem-resultaat: // ... .getForEntity ("/ hallo", String :: class.java) assertNotNull (resultaat) assertEquals (resultaat? .statusCode, HttpStatus.OK) assertEquals (resultaat? .body, "hallo wereld")}}

Deze test laat een van de zeer krachtige functies van Kotlin zien: veiligheid niet! Kotlin-variabelen die null kunnen zijn, moeten worden gedeclareerd met ‘? '. De compiler weet dan dat defensieve codering vereist is voordat hij toegang krijgt tot die eigenschap.

In onze test TestRestTemplate wordt gedefinieerd als een nullable type, en elke keer dat we er toegang toe krijgen, doen we dit met behulp van de nulcoalescente operator "?". - die null retourneert als het aangeroepen object null is.

Dit verduidelijkt het gebruik van null-waarden in het programma en dwingt ontwikkelaars om veilige code te schrijven wanneer ze ermee werken.

Laten we vervolgens een service toevoegen en die in onze controller integreren.

5. Service

Zoals u nu waarschijnlijk wel kunt raden, zal onze service vrij eenvoudig aan ons project toe te voegen. Laten we dat nu doen:

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

Vrij eenvoudige service hier met een enkele functie die een String retourneert. Laten we vervolgens onze service aansluiten op de controller en deze gebruiken om een ​​waarde te retourneren:

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

Ahh, dat ziet er leuk uit! In Kotlin kan de hoofdconstructor worden gedefinieerd in lijn met de klassendeclaratie. We hebben de @Autowired annotatie van onze constructor omdat het sinds enige tijd niet meer verplicht is.

Die parameters worden automatisch geconverteerd naar velden in de klas. Kotlin ze worden eigenschappen genoemd. Er zijn geen getters of setters gedefinieerd; ze worden automatisch aangemaakt. U kunt deze standaardinstellingen natuurlijk overschrijven als u dat wilt.

In Kotlin kunnen eigenschappen in klassen en variabelen in functies worden gedefinieerd met behulp van var of val. Var geeft een veranderlijke eigenschap aan, en val geeft een laatste aan. Hierdoor kan de compiler controleren op illegale toegang. Sinds onze HalloService is een singleton, we bedraden het als een val om mutatie te voorkomen.

Laten we vervolgens een test toevoegen voor deze controllermethode:

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

Laten we tot slot eens kijken hoe een POJO eruitziet in Kotlin.

6. Kotlin-gegevensklasse

In Java vertegenwoordigen we data-objecten met gewone oude Java-objecten, de POJO. In Kotlin hebben we iets waarmee we dit type object beknopter kunnen uitdrukken - een dataklasse.

Laten we een data-object schrijven om terug te sturen naar onze controller:

dataklasse HelloDto (val begroeting: String)

Dat was geen truc. Ik laat niets weg uit onze klas. Met de datamodificator krijgen we veel voordelen. Dit trefwoord maakt automatisch een is gelijk aan / hashcode paar, een toString functie en een kopieerfunctie. Dat alles uit een oneliner van 53 tekens!

Laten we nu een methode toevoegen om onze nieuwe dataklasse te retourneren:

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

De datamodificator voegt geen standaardconstructor toe, wat belangrijk is voor bepaalde bibliotheken zoals Jackson. Om dit type klasse te ondersteunen hebben we de jackson-module-kotlin naar ons POM-bestand om marshaling te ondersteunen. Dit is gedaan tijdens sectie 2, en je kunt de afhankelijkheid daar zien.

Laten we tot slot een test toevoegen voor deze controllerfunctie:

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

7. Conclusie

In dit artikel hebben we gekeken naar Kotlin-ondersteuning in Spring Boot 2.x. We zagen aan de hand van voorbeelden dat Kotlin onze applicaties kon vereenvoudigen en verbeteren door ons te dwingen kortere, veiligere code te schrijven.

Kotlin ondersteunt ook enkele geweldige functies zoals de dataklasse, klasse-extensies en is volledig compatibel met bestaande Java-code. Dit betekent dat je Kotlin-code kunt schrijven en deze kunt aanroepen vanuit je Java-klassen en vice versa. Bovendien is Kotlin vanaf de grond af opgebouwd om fantastische ondersteuning te hebben in een IDE, en dat doet het ook.

Er zijn veel redenen om Kotlin uit te proberen, en met Google en Spring die het steunen, is dit het moment om het uit te proberen. Laat ons weten wat je hebt besloten om ermee te bouwen!

Je kunt de broncode altijd vinden op GitHub.