@ -30,6 +30,7 @@ Spring application developers.
@@ -30,6 +30,7 @@ Spring application developers.
[[use-cases]]
== Use cases
In addition to providing an explicit declaration for Spring Framework API nullability,
@ -43,6 +44,7 @@ are available in the <<languages#kotlin-null-safety, Kotlin support documentatio
@@ -43,6 +44,7 @@ are available in the <<languages#kotlin-null-safety, Kotlin support documentatio
[[jsr-305-meta-annotations]]
== JSR-305 meta-annotations
Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]
@ -296,6 +296,7 @@ for more details and up-to-date information. See also the experimental Kofu DSL
@@ -296,6 +296,7 @@ for more details and up-to-date information. See also the experimental Kofu DSL
[[router-dsl]]
=== Router DSL
Spring Framework comes with a Kotlin router DSL available in 3 flavors:
@ -339,6 +340,7 @@ See https://github.com/mixitconf/mixit/[MiXiT project] for a concrete example.
@@ -339,6 +340,7 @@ See https://github.com/mixitconf/mixit/[MiXiT project] for a concrete example.
[[mockmvc-dsl]]
=== MockMvc DSL
A Kotlin DSL is provided via `MockMvc` Kotlin extensions in order to provide a more
@ -413,6 +416,7 @@ project for more details.
@@ -413,6 +416,7 @@ project for more details.
[[kotlin-multiplatform-serialization]]
=== Kotlin multiplatform serialization
As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is
@ -427,6 +431,7 @@ if Jackson is needed configure `KotlinSerializationJsonMessageConverter` manuall
@@ -427,6 +431,7 @@ if Jackson is needed configure `KotlinSerializationJsonMessageConverter` manuall
[[coroutines]]
== Coroutines
Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin
@ -447,6 +452,7 @@ Spring Framework provides support for Coroutines on the following scope:
@@ -447,6 +452,7 @@ Spring Framework provides support for Coroutines on the following scope:
[[dependencies]]
=== Dependencies
Coroutines support is enabled when `kotlinx-coroutines-core` and `kotlinx-coroutines-reactor`
@ -466,6 +472,7 @@ Version `1.4.0` and above are supported.
@@ -466,6 +472,7 @@ Version `1.4.0` and above are supported.
[[how-reactive-translates-to-coroutines?]]
=== How Reactive translates to Coroutines?
For return values, the translation from Reactive to Coroutines APIs is the following:
@ -494,6 +501,7 @@ for more details, including how to run code concurrently with Coroutines.
@@ -494,6 +501,7 @@ for more details, including how to run code concurrently with Coroutines.
[[controllers]]
=== Controllers
Here is an example of a Coroutines `@RestController`.
@ -592,6 +600,7 @@ class CoroutinesViewController(banner: Banner) {
@@ -592,6 +600,7 @@ class CoroutinesViewController(banner: Banner) {
[[webflux-fn]]
=== WebFlux.fn
Here is an example of Coroutines router defined via the {docs-spring-framework}/kdoc-api/spring-webflux/org.springframework.web.reactive.function.server/co-router.html[coRouter { }] DSL and related handlers.
@ -627,6 +636,7 @@ class UserHandler(builder: WebClient.Builder) {
@@ -627,6 +636,7 @@ class UserHandler(builder: WebClient.Builder) {
[[transactions]]
=== Transactions
Transactions on Coroutines are supported via the programmatic variant of the Reactive
@ -686,6 +696,7 @@ in Kotlin.
@@ -686,6 +696,7 @@ in Kotlin.
[[final-by-default]]
=== Final by Default
By default, https://discuss.kotlinlang.org/t/classes-final-by-default/166[all classes in Kotlin are `final`].
@ -727,6 +738,7 @@ using the `kotlin-allopen` plugin, since this is the most commonly used setup.
@@ -727,6 +738,7 @@ using the `kotlin-allopen` plugin, since this is the most commonly used setup.
=== Using Immutable Class Instances for Persistence
In Kotlin, it is convenient and considered to be a best practice to declare read-only properties
@ -772,6 +784,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object
@@ -772,6 +784,7 @@ does not require the `kotlin-noarg` plugin if the module uses Spring Data object
[[injecting-dependencies]]
=== Injecting Dependencies
Our recommendation is to try to favor constructor injection with `val` read-only (and
@ -809,6 +822,7 @@ as the following example shows:
@@ -809,6 +822,7 @@ as the following example shows:
[[injecting-configuration-properties]]
=== Injecting Configuration Properties
In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value("${property}")`)].
@ -850,6 +864,7 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl
@@ -850,6 +864,7 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl
[[checked-exceptions]]
=== Checked Exceptions
Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]
@ -864,6 +879,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce
@@ -864,6 +879,7 @@ to specify explicitly the checked exceptions thrown (for example `@Throws(IOExce
[[annotation-array-attributes]]
=== Annotation Array Attributes
Kotlin annotations are mostly similar to Java annotations, but array attributes (which are
@ -910,6 +926,7 @@ be matched, not only the `GET` method.
@@ -910,6 +926,7 @@ be matched, not only the `GET` method.
[[testing]]
=== Testing
This section addresses testing with the combination of Kotlin and Spring Framework.
@ -920,6 +937,7 @@ NOTE: If you are using Spring Boot, see
@@ -920,6 +937,7 @@ NOTE: If you are using Spring Boot, see
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-kotlin-testing[this related documentation].
[[constructor-injection]]
==== Constructor injection
As described in the <<testing#testcontext-junit-jupiter-di, dedicated section>>,
@ -942,6 +960,7 @@ class OrderServiceIntegrationTests(val orderService: OrderService,
@@ -942,6 +960,7 @@ class OrderServiceIntegrationTests(val orderService: OrderService,
====
[[per_class-lifecycle]]
==== `PER_CLASS` Lifecycle
Kotlin lets you specify meaningful test function names between backticks (```).
@ -986,6 +1005,7 @@ class IntegrationTests {
@@ -986,6 +1005,7 @@ class IntegrationTests {
----
[[specification-like-tests]]
==== Specification-like Tests
You can create specification-like tests with JUnit 5 and Kotlin.
The easiest way to start a new Spring Framework project in Kotlin is to create a new Spring
@ -1043,6 +1064,7 @@ Boot 2 project on https://start.spring.io/#!language=kotlin&type=gradle-project[
@@ -1043,6 +1064,7 @@ Boot 2 project on https://start.spring.io/#!language=kotlin&type=gradle-project[
[[choosing-the-web-flavor]]
=== Choosing the Web Flavor
Spring Framework now comes with two different web stacks: <<web#mvc, Spring MVC>> and
@ -1073,6 +1095,7 @@ Kotlin and the Spring Framework:
@@ -1073,6 +1095,7 @@ Kotlin and the Spring Framework:
[[examples]]
=== Examples
The following Github projects offer examples that you can learn from and possibly even extend:
@ -1087,6 +1110,7 @@ The following Github projects offer examples that you can learn from and possibl
@@ -1087,6 +1110,7 @@ The following Github projects offer examples that you can learn from and possibl
[[issues]]
=== Issues
The following list categorizes the pending issues related to Spring and Kotlin support:
@ -38,6 +38,7 @@ test execution by providing dependency injection, managing transactions, and so
@@ -38,6 +38,7 @@ test execution by providing dependency injection, managing transactions, and so
class. See the {api-spring-framework}/test/context/package-summary.html[javadoc] and the
Spring test suite for further information and examples of various implementations.
[[testcontext]]
=== `TestContext`
`TestContext` encapsulates the context in which a test is run (agnostic of the
@ -45,6 +46,7 @@ actual testing framework in use) and provides context management and caching sup
@@ -45,6 +46,7 @@ actual testing framework in use) and provides context management and caching sup
the test instance for which it is responsible. The `TestContext` also delegates to a
`SmartContextLoader` to load an `ApplicationContext` if requested.
[[testcontextmanager]]
=== `TestContextManager`
`TestContextManager` is the main entry point into the Spring TestContext Framework and is
@ -59,11 +61,13 @@ responsible for managing a single `TestContext` and signaling events to each reg
@@ -59,11 +61,13 @@ responsible for managing a single `TestContext` and signaling events to each reg
* After any "`after`" or "`after each`" methods of a particular testing framework.
* After any "`after class`" or "`after all`" methods of a particular testing framework.
[[testexecutionlistener]]
=== `TestExecutionListener`
`TestExecutionListener` defines the API for reacting to test-execution events published by
the `TestContextManager` with which the listener is registered. See <<testcontext-tel-config>>.
[[context-loaders]]
=== Context Loaders
`ContextLoader` is a strategy interface for loading an `ApplicationContext` for an
@ -1732,6 +1736,7 @@ through the `getPropertySourceLocations()` and `getPropertySourceProperties()` m
@@ -1732,6 +1736,7 @@ through the `getPropertySourceLocations()` and `getPropertySourceProperties()` m
`MergedContextConfiguration`.
====
[[declaring-test-property-sources]]
==== Declaring Test Property Sources
You can configure test properties files by using the `locations` or `value` attribute of
If `@TestPropertySource` is declared as an empty annotation (that is, without explicit
@ -1838,6 +1844,7 @@ if the annotated test class is `com.example.MyTest`, the corresponding default p
@@ -1838,6 +1844,7 @@ if the annotated test class is `com.example.MyTest`, the corresponding default p
file is `classpath:com/example/MyTest.properties`. If the default cannot be detected, an
`IllegalStateException` is thrown.
[[precedence]]
==== Precedence
Test properties have higher precedence than those defined in the operating system's
@ -1881,6 +1888,7 @@ to specify properties both in a file and inline:
@@ -1881,6 +1888,7 @@ to specify properties both in a file and inline:
@ -102,6 +103,7 @@ You can shorten it further still with a full URI template, as the following exam
@@ -102,6 +103,7 @@ You can shorten it further still with a full URI template, as the following exam
[id={chapter}.web-uribuilder]
[[uribuilder]]
= UriBuilder
[.small]#Spring MVC and Spring WebFlux#
@ -194,6 +196,7 @@ that holds configuration and preferences, as the following example shows:
@@ -194,6 +196,7 @@ that holds configuration and preferences, as the following example shows:
@ -869,6 +869,7 @@ inline-style, through the built-in `BodyInserters`, as the following example sho
@@ -869,6 +869,7 @@ inline-style, through the built-in `BodyInserters`, as the following example sho
.awaitBody<Unit>()
----
[[partevent]]
==== `PartEvent`
To stream multipart data sequentially, you can provide multipart content through `PartEvent`
The original web framework included in the Spring Framework, Spring Web MVC, was
@ -248,6 +249,7 @@ current thread (and rely on callbacks instead) means that you do not need extra
@@ -248,6 +249,7 @@ current thread (and rely on callbacks instead) means that you do not need extra
there are no blocking calls to absorb.
[[invoking-a-blocking-api]]
==== Invoking a Blocking API
What if you do need to use a blocking library? Both Reactor and RxJava provide the
@ -255,6 +257,7 @@ What if you do need to use a blocking library? Both Reactor and RxJava provide t
@@ -255,6 +257,7 @@ What if you do need to use a blocking library? Both Reactor and RxJava provide t
easy escape hatch. Keep in mind, however, that blocking APIs are not a good fit for
this concurrency model.
[[mutable-state]]
==== Mutable State
In Reactor and RxJava, you declare logic through operators. At runtime, a reactive
@ -262,6 +265,7 @@ pipeline is formed where data is processed sequentially, in distinct stages. A k
@@ -262,6 +265,7 @@ pipeline is formed where data is processed sequentially, in distinct stages. A k
of this is that it frees applications from having to protect mutable state because
application code within that pipeline is never invoked concurrently.
[[threading-model]]
==== Threading Model
What threads should you expect to see on a server running with Spring WebFlux?
@ -287,6 +291,7 @@ specific thread pool `Scheduler` strategy.
@@ -287,6 +291,7 @@ specific thread pool `Scheduler` strategy.
* Data access libraries and other third party dependencies can also create and use threads
of their own.
[[configuring]]
==== Configuring
The Spring Framework does not provide support for starting and stopping
@ -2841,6 +2846,7 @@ as the following example shows:
@@ -2841,6 +2846,7 @@ as the following example shows:
<1> Using `@RequestBody`.
--
[[partevent]]
===== `PartEvent`
To access multipart data sequentially, in a streaming fashion, you can use `@RequestBody` with
@ -599,6 +599,7 @@ The following example shows the composition of four routes:
@@ -599,6 +599,7 @@ The following example shows the composition of four routes:
<4> `otherRoute` is a router function that is created elsewhere, and added to the route built.
[[nested-routes]]
=== Nested Routes
It is common for a group of router functions to have a shared predicate, for instance a shared
The WebSocket protocol, https://tools.ietf.org/html/rfc6455[RFC 6455], provides a standardized
@ -55,6 +56,7 @@ instructions of the cloud provider related to WebSocket support.
@@ -55,6 +56,7 @@ instructions of the cloud provider related to WebSocket support.
[id={chapter}.websocket-intro-architecture]
[[http-versus-websocket]]
== HTTP Versus WebSocket
Even though WebSocket is designed to be HTTP-compatible and starts with an HTTP request,
@ -81,6 +83,7 @@ In the absence of that, they need to come up with their own conventions.
@@ -81,6 +83,7 @@ In the absence of that, they need to come up with their own conventions.
[id={chapter}.websocket-intro-when-to-use]
[[when-to-use-websockets]]
== When to Use WebSockets
WebSockets can make a web page be dynamic and interactive. However, in many cases,
@ -1226,6 +1226,7 @@ referenced through `@DestinationVariable` method arguments. Applications can als
@@ -1226,6 +1226,7 @@ referenced through `@DestinationVariable` method arguments. Applications can als
a dot-separated destination convention for mappings, as explained in
<<websocket-stomp-destination-separator>>.
[[supported-method-arguments]]
===== Supported Method Arguments
The following table describes the method arguments:
@ -1270,6 +1271,7 @@ Values are converted to the declared method argument type as necessary.
@@ -1270,6 +1271,7 @@ Values are converted to the declared method argument type as necessary.
|===
[[return-values]]
===== Return Values
By default, the return value from a `@MessageMapping` method is serialized to a payload