From 889a06b65b531206a3be4bbbf6fc2317052e38f7 Mon Sep 17 00:00:00 2001 From: sdeleuze Date: Thu, 15 Feb 2018 11:20:08 +0100 Subject: [PATCH] Add Kotlin support reference documentation See gh-12073 --- .../src/main/asciidoc/index.adoc | 3 + .../main/asciidoc/spring-boot-features.adoc | 206 ++++++++++++++++++ 2 files changed, 209 insertions(+) diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/index.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/index.adoc index ffbc173c03..2faecdeea5 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/index.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/index.adoc @@ -15,6 +15,7 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson; :github-repo: spring-projects/spring-boot :github-raw: https://raw.github.com/{github-repo}/{github-tag} :github-code: https://github.com/{github-repo}/tree/{github-tag} +:github-issues: https://github.com/{github-repo}/issues/ :github-wiki: https://github.com/{github-repo}/wiki :github-master-code: https://github.com/{github-repo}/tree/master :sc-ext: java @@ -68,6 +69,8 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson; :jetty-documentation: https://www.eclipse.org/jetty/documentation/9.4.x :micrometer-concepts-documentation: https://micrometer.io/docs/concepts :tomcat-documentation: https://tomcat.apache.org/tomcat-8.5-doc +:kotlin-documentation: https://kotlinlang.org/docs/reference/ +:junit5-documentation: https://junit.org/junit5/docs/current/user-guide // ====================================================================================== include::documentation-overview.adoc[] diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index e7eb5e981f..d0f0145741 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -7533,6 +7533,212 @@ relies on another starter). If a project is created with only your custom starte Boot's core features will be honoured by the presence of the core starter. +[[kotlin]] +== Kotlin support + +https://kotlinlang.org[Kotlin] is a statically-typed language targeting the JVM (and other +platforms) which allows writing concise and elegant code while providing very good +{kotlin-documentation}java-interop.html[interoperability] with +existing libraries written in Java. + +As of version 2.0, Spring Boot provides Kotlin support leveraging other Spring projects +Kotlin support like Spring Framework, Spring Data and Reactor. See the +{spring-reference}languages.html#kotlin[Spring Framework Kotlin support] documentation +for more information. + +The easy way to start with Spring Boot and Kotlin is to create a project via +https://start.spring.io/#!language=kotlin[start.spring.io]. Feel free to join the #spring +channel of http://slack.kotlinlang.org/[Kotlin Slack] or ask a question with `spring` +and `kotlin` tags on https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] +if you need support. + + +[[kotlin-requirements]] +=== Requirements + +Spring Boot supports Kotlin 1.2+ and requires +https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib[`kotlin-stdlib`] +(or one of its https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib-jdk7[`kotlin-stdlib-jdk7`] +/ https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-stdlib-jdk8[`kotlin-stdlib-jdk8`] variants) +and https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-reflect[`kotlin-reflect`] +to be present on the classpath. + +Since https://discuss.kotlinlang.org/t/classes-final-by-default/166[classes are final by default in Kotlin], +you are likely to want to configure +{kotlin-documentation}compiler-plugins.html#spring-support[kotlin-spring] +plugin in order to automatically open Spring-annotated classes. + +https://github.com/FasterXML/jackson-module-kotlin[Jackson Kotlin module] which is required +for serializing / deserializing JSON data is automatically registered when +found in the classpath and a warning message will be logged if Jackson and Kotlin are +detected without the Jackson Kotlin module present. + +These dependencies and plugins are provided by default if one bootstraps a Kotlin project on +https://start.spring.io/#!language=kotlin[start.spring.io]. + + +[[kotlin-null-safety]] +=== Null-safety + +One of Kotlin's key features is {kotlin-documentation}null-safety.html[null-safety] +- which cleanly deals with `null` values at compile time rather than bumping into the +famous `NullPointerException` at runtime. This makes applications safer through +nullability declarations and expressing "value or no value" semantics without paying the +cost of wrappers like `Optional`. (Kotlin allows using functional constructs with nullable +values; check out this +http://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].) + +Although Java does not allow one to express null-safety in its type-system, Spring +Framework, Spring Data and Reactor now provides null-safety of their API via +tooling-friendly annotations. By default, types from Java APIs used in Kotlin are +recognized as +{kotlin-documentation}java-interop.html#null-safety-and-platform-types[platform types] +for which null-checks are relaxed. +{kotlin-documentation}java-interop.html#jsr-305-support[Kotlin support for JSR 305 annotations] ++ Spring nullability annotations provide null-safety for the related Spring API to Kotlin +developers, with the advantage of dealing with `null` related issues at compile time. + +The JSR 305 checks can be configured by adding the `-Xjsr305` compiler flag with the +following options: `-Xjsr305={strict|warn|ignore}`. The default behavior is the same to +`-Xjsr305=warn`. The `strict` value is required to have null-safety taken in account in +Kotlin types inferred from Spring API but should be used with the knowledge that Spring +API nullability declaration could evolve even between minor releases and more checks may +be added in the future). + +Note: Generic type arguments, varargs and array elements nullability are not supported yet, +but should be in an upcoming release, see https://jira.spring.io/browse/SPR-15942[SPR-15942] +for up-to-date information. Also be aware that Spring Boot own API is +{github-issues}10712[not annotated yet]. + + +[[kotlin-api]] +=== Kotlin API + +[[kotlin-api-runapplication]] +==== runApplication + +Spring Boot provides a Kotlin idiomatic way to run an application with +`runApplication(*args)` which is a drop in replacement for +`SpringApplication.run(FooApplication::class.java, *args)`. + +[source,kotlin,indent=0] +---- +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication + +@SpringBootApplication +class FooApplication + +fun main(args: Array) { + runApplication(*args) +} +---- + +It also allows to customize the application thanks to the following syntax: + +[source,kotlin,indent=0] +---- +runApplication(*args) { + setBannerMode(OFF) +} +---- + +[[kotlin-api-extensions]] +==== Extensions + +Kotlin {kotlin-documentation}extensions.html[extensions] provide the ability +to extend existing classes with additional functionality. The Spring Boot Kotlin API makes +use of these extensions to add new Kotlin specific conveniences to existing Spring APIs. + +`TestRestTemplate` extensions are provided similar to the `RestOperations` ones in order +to be able to take advantage of Kotlin reified type parameters for example. + + +[[kotlin-dependency-management]] +=== Dependency management + +Dependency management of the following Kotlin dependencies is provided in order to avoid +mixing different version of Kotlin dependencies in the classpath: + + - `kotlin-reflect` + - `kotlin-runtime` + - `kotlin-stdlib` + - `kotlin-stdlib-jdk7` + - `kotlin-stdlib-jdk8` + - `kotlin-stdlib-jre7` + - `kotlin-stdlib-jre8` + +More dependencies should be managed {github-issues}9486[when a Kotlin BOM] will be available. + +With Maven, the Kotlin version can be customized via the `kotlin.version` property and +plugin management is provided for `kotlin-maven-plugin`. With Gradle, Spring Boot plugin +automatically defines `kotlin.version` based on the version +specified for the Kotlin plugin. + + +=== @ConfigurationProperties + +`@ConfigurationProperties` currently only works with `lateinit` or nullable `var` properties +(the former is recommended) since immutable classes initialized by constructors are not +supported yet until {github-issues}8762[this issue] is fixed. + +[source,kotlin,indent=0] +---- +@ConfigurationProperties("foo") +class FooProperties { + lateinit var foo1: String + lateinit var foo2: String + lateinit val bar = Bar() + + class Bar { + lateinit var bar1: String + lateinit var bar2: String + } +} +---- + + +[[kotlin-testing]] +=== Testing + +While using JUnit 4 (used by default in `spring-boot-starter-test`) is possible, JUnit 5 +enables a single instantiation of test classes which makes it possible to use `@BeforeAll` +and `@AfterAll` annotations on non-static methods, which is a good fit for Kotlin. + +To use it, you need to exclude `junit:junit` dependency from `spring-boot-starter-test` +and add JUnit 5 dependencies and configure Maven/Gradle plugin accordingly, see +{junit5-documentation}/#dependency-metadata-junit-jupiter-samples[JUnit 5 +documentation] for more details. You also need to +{junit5-documentation}/#writing-tests-test-instance-lifecycle-changing-default[switch test +instance lifecycle to "per-class"]. + + +[[kotlin-resources]] +=== Resources + +* {kotlin-documentation}[Kotlin language reference] +* http://slack.kotlinlang.org/[Kotlin Slack] (with a dedicated #spring channel) +* https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow with `spring` and `kotlin` tags] +* https://try.kotlinlang.org/[Try Kotlin in your browser] +* https://blog.jetbrains.com/kotlin/[Kotlin blog] +* https://kotlin.link/[Awesome Kotlin] + +=== Blog posts + +* https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin[Developing Spring Boot applications with Kotlin] +* https://spring.io/blog/2016/03/20/a-geospatial-messenger-with-kotlin-spring-boot-and-postgresql[A Geospatial Messenger with Kotlin, Spring Boot and PostgreSQL] +* https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0[Introducing Kotlin support in Spring Framework 5.0] +* https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way[Spring Framework 5 Kotlin APIs, the functional way] + +=== Examples + +* https://github.com/sdeleuze/spring-boot-kotlin-demo[spring-boot-kotlin-demo]: regular Spring Boot + Spring Data JPA project +* https://github.com/mixitconf/mixit[mixit]: Spring Boot 2 + WebFlux + Reactive Spring Data MongoDB +* https://github.com/sdeleuze/spring-kotlin-fullstack[spring-kotlin-fullstack]: WebFlux Kotlin fullstack example with Kotlin2js for frontend instead of JavaScript or TypeScript +* https://github.com/spring-petclinic/spring-petclinic-kotlin[spring-petclinic-kotlin]: Kotlin version of the Spring PetClinic Sample Application +* https://github.com/sdeleuze/spring-kotlin-deepdive[spring-kotlin-deepdive]: a step by step migration for Boot 1.0 + Java to Boot 2.0 + Kotlin + + [[boot-features-whats-next]] == What to Read Next