Additional documentation notes on Java/Kotlin parameter name retention
See gh-29563
This commit is contained in:
parent
a27f2e994b
commit
b7e99fbe30
|
|
@ -20,6 +20,9 @@ Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Sl
|
|||
or ask a question with `spring` and `kotlin` as tags on
|
||||
https://stackoverflow.com/questions/tagged/spring+kotlin[Stackoverflow] if you need support.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-requirements]]
|
||||
== Requirements
|
||||
|
||||
|
|
@ -37,6 +40,9 @@ for serializing or deserializing JSON data for Kotlin classes with Jackson, so m
|
|||
`com.fasterxml.jackson.module:jackson-module-kotlin` dependency to your project if you have such need.
|
||||
It is automatically registered when found in the classpath.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-extensions]]
|
||||
== Extensions
|
||||
|
||||
|
|
@ -80,6 +86,9 @@ With Kotlin and the Spring Framework extensions, you can instead write the follo
|
|||
As in Java, `users` in Kotlin is strongly typed, but Kotlin's clever type inference allows
|
||||
for shorter syntax.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-null-safety]]
|
||||
== Null-safety
|
||||
|
||||
|
|
@ -115,6 +124,9 @@ NOTE: Generic type arguments, varargs, and array elements nullability are not su
|
|||
but should be in an upcoming release. See https://github.com/Kotlin/KEEP/issues/79[this discussion]
|
||||
for up-to-date information.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-classes-interfaces]]
|
||||
== Classes and Interfaces
|
||||
|
||||
|
|
@ -124,12 +136,16 @@ with default values.
|
|||
|
||||
Kotlin parameter names are recognized through a dedicated `KotlinReflectionParameterNameDiscoverer`,
|
||||
which allows finding interface method parameter names without requiring the Java 8 `-parameters`
|
||||
compiler flag to be enabled during compilation.
|
||||
compiler flag to be enabled during compilation. (For completeness, we nevertheless recommend
|
||||
running the Kotlin compiler with its `-java-parameters` flag for standard Java parameter exposure.)
|
||||
|
||||
You can declare configuration classes as
|
||||
https://kotlinlang.org/docs/reference/nested-classes.html[top level or nested but not inner],
|
||||
since the later requires a reference to the outer class.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-annotations]]
|
||||
== Annotations
|
||||
|
||||
|
|
@ -156,6 +172,9 @@ https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targe
|
|||
such as `@field:NotNull` or `@get:Size(min=5, max=15)`, as described in
|
||||
https://stackoverflow.com/a/35853200/1092077[this Stack Overflow response].
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-bean-definition-dsl]]
|
||||
== Bean Definition DSL
|
||||
|
||||
|
|
@ -263,16 +282,20 @@ as the following example shows:
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
NOTE: Spring Boot is based on JavaConfig and
|
||||
https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],
|
||||
but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.
|
||||
See https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-definition-kotlin-dsl-with-spring-boot-and-spring-w/46033685#46033685[this Stack Overflow answer]
|
||||
for more details and up-to-date information. See also the experimental Kofu DSL developed in https://github.com/spring-projects/spring-fu[Spring Fu incubator].
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-web]]
|
||||
== Web
|
||||
|
||||
|
||||
|
||||
=== Router DSL
|
||||
|
||||
Spring Framework comes with a Kotlin router DSL available in 3 flavors:
|
||||
|
|
@ -314,6 +337,8 @@ when you need to register routes depending on dynamic data (for example, from a
|
|||
|
||||
See https://github.com/mixitconf/mixit/[MiXiT project] for a concrete example.
|
||||
|
||||
|
||||
|
||||
=== MockMvc DSL
|
||||
|
||||
A Kotlin DSL is provided via `MockMvc` Kotlin extensions in order to provide a more
|
||||
|
|
@ -339,6 +364,8 @@ mockMvc.get("/person/{name}", "Lee") {
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
=== Kotlin Script Templates
|
||||
|
||||
Spring Framework provides a
|
||||
|
|
@ -357,9 +384,7 @@ dependencies {
|
|||
}
|
||||
----
|
||||
|
||||
Configuration is usually done with `ScriptTemplateConfigurer` and `ScriptTemplateViewResolver`
|
||||
beans.
|
||||
|
||||
Configuration is usually done with `ScriptTemplateConfigurer` and `ScriptTemplateViewResolver` beans.
|
||||
|
||||
`KotlinScriptConfiguration.kt`
|
||||
[source,kotlin,indent=0]
|
||||
|
|
@ -386,6 +411,8 @@ class KotlinScriptConfiguration {
|
|||
See the https://github.com/sdeleuze/kotlin-script-templating[kotlin-script-templating] example
|
||||
project for more details.
|
||||
|
||||
|
||||
|
||||
=== Kotlin multiplatform serialization
|
||||
|
||||
As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is
|
||||
|
|
@ -397,6 +424,9 @@ Kotlin serialization is designed to serialize only Kotlin classes annotated with
|
|||
With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,
|
||||
if Jackson is needed configure `KotlinSerializationJsonMessageConverter` manually.
|
||||
|
||||
|
||||
|
||||
|
||||
== Coroutines
|
||||
|
||||
Kotlin https://kotlinlang.org/docs/reference/coroutines-overview.html[Coroutines] are Kotlin
|
||||
|
|
@ -415,6 +445,8 @@ Spring Framework provides support for Coroutines on the following scope:
|
|||
* Suspending function and `Flow` support in RSocket `@MessageMapping` annotated methods
|
||||
* Extensions for {docs-spring-framework}/kdoc-api/spring-messaging/org.springframework.messaging.rsocket/index.html[`RSocketRequester`]
|
||||
|
||||
|
||||
|
||||
=== Dependencies
|
||||
|
||||
Coroutines support is enabled when `kotlinx-coroutines-core` and `kotlinx-coroutines-reactor`
|
||||
|
|
@ -432,6 +464,8 @@ dependencies {
|
|||
|
||||
Version `1.4.0` and above are supported.
|
||||
|
||||
|
||||
|
||||
=== How Reactive translates to Coroutines?
|
||||
|
||||
For return values, the translation from Reactive to Coroutines APIs is the following:
|
||||
|
|
@ -458,6 +492,8 @@ https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coro
|
|||
Read this blog post about https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow[Going Reactive with Spring, Coroutines and Kotlin Flow]
|
||||
for more details, including how to run code concurrently with Coroutines.
|
||||
|
||||
|
||||
|
||||
=== Controllers
|
||||
|
||||
Here is an example of a Coroutines `@RestController`.
|
||||
|
|
@ -554,6 +590,8 @@ class CoroutinesViewController(banner: Banner) {
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
=== 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.
|
||||
|
|
@ -587,6 +625,8 @@ class UserHandler(builder: WebClient.Builder) {
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
=== Transactions
|
||||
|
||||
Transactions on Coroutines are supported via the programmatic variant of the Reactive
|
||||
|
|
@ -636,6 +676,8 @@ For Kotlin `Flow`, a `Flow<T>.transactional` extension is provided.
|
|||
----
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-spring-projects-in-kotlin]]
|
||||
== Spring Projects in Kotlin
|
||||
|
||||
|
|
@ -683,6 +725,8 @@ NOTE: The Kotlin code samples in Spring Framework documentation do not explicitl
|
|||
`open` on the classes and their member functions. The samples are written for projects
|
||||
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
|
||||
|
|
@ -726,6 +770,8 @@ NOTE: As of the Kay release train, Spring Data supports Kotlin immutable class i
|
|||
does not require the `kotlin-noarg` plugin if the module uses Spring Data object mappings
|
||||
(such as MongoDB, Redis, Cassandra, and others).
|
||||
|
||||
|
||||
|
||||
=== Injecting Dependencies
|
||||
|
||||
Our recommendation is to try to favor constructor injection with `val` read-only (and
|
||||
|
|
@ -761,6 +807,8 @@ as the following example shows:
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
=== Injecting Configuration Properties
|
||||
|
||||
In Java, you can inject configuration properties by using annotations (such as pass:q[`@Value("${property}")`)].
|
||||
|
|
@ -801,6 +849,7 @@ that uses the `${...}` syntax, with configuration beans, as the following exampl
|
|||
----
|
||||
|
||||
|
||||
|
||||
=== Checked Exceptions
|
||||
|
||||
Java and https://kotlinlang.org/docs/reference/exceptions.html[Kotlin exception handling]
|
||||
|
|
@ -813,6 +862,8 @@ To get the original exception thrown like in Java, methods should be annotated w
|
|||
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html[`@Throws`]
|
||||
to specify explicitly the checked exceptions thrown (for example `@Throws(IOException::class)`).
|
||||
|
||||
|
||||
|
||||
=== Annotation Array Attributes
|
||||
|
||||
Kotlin annotations are mostly similar to Java annotations, but array attributes (which are
|
||||
|
|
@ -857,6 +908,8 @@ use a shortcut annotation, such as `@GetMapping`, `@PostMapping`, and others.
|
|||
NOTE: If the `@RequestMapping` `method` attribute is not specified, all HTTP methods will
|
||||
be matched, not only the `GET` method.
|
||||
|
||||
|
||||
|
||||
=== Testing
|
||||
|
||||
This section addresses testing with the combination of Kotlin and Spring Framework.
|
||||
|
|
@ -866,6 +919,7 @@ https://mockk.io/[Mockk] for mocking.
|
|||
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
|
||||
|
||||
As described in the <<testing#testcontext-junit-jupiter-di, dedicated section>>,
|
||||
|
|
@ -887,6 +941,7 @@ class OrderServiceIntegrationTests(val orderService: OrderService,
|
|||
----
|
||||
====
|
||||
|
||||
|
||||
==== `PER_CLASS` Lifecycle
|
||||
|
||||
Kotlin lets you specify meaningful test function names between backticks (```).
|
||||
|
|
@ -930,6 +985,7 @@ class IntegrationTests {
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
==== Specification-like Tests
|
||||
|
||||
You can create specification-like tests with JUnit 5 and Kotlin.
|
||||
|
|
@ -959,6 +1015,7 @@ class SpecificationLikeTests {
|
|||
}
|
||||
----
|
||||
|
||||
|
||||
[[kotlin-webtestclient-issue]]
|
||||
==== `WebTestClient` Type Inference Issue in Kotlin
|
||||
|
||||
|
|
@ -968,17 +1025,24 @@ since it provides a workaround for the Kotlin issue with the Java API.
|
|||
|
||||
See also the related https://jira.spring.io/browse/SPR-16057[SPR-16057] issue.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-getting-started]]
|
||||
== Getting Started
|
||||
|
||||
The easiest way to learn how to build a Spring application with Kotlin is to follow
|
||||
https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].
|
||||
|
||||
|
||||
|
||||
=== `start.spring.io`
|
||||
|
||||
The easiest way to start a new Spring Framework project in Kotlin is to create a new Spring
|
||||
Boot 2 project on https://start.spring.io/#!language=kotlin&type=gradle-project[start.spring.io].
|
||||
|
||||
|
||||
|
||||
=== Choosing the Web Flavor
|
||||
|
||||
Spring Framework now comes with two different web stacks: <<web#mvc, Spring MVC>> and
|
||||
|
|
@ -991,6 +1055,9 @@ Kotlin DSL.
|
|||
For other use cases, especially if you are using blocking technologies such as JPA, Spring
|
||||
MVC and its annotation-based programming model is the recommended choice.
|
||||
|
||||
|
||||
|
||||
|
||||
[[kotlin-resources]]
|
||||
== Resources
|
||||
|
||||
|
|
@ -1004,6 +1071,8 @@ Kotlin and the Spring Framework:
|
|||
* https://blog.jetbrains.com/kotlin/[Kotlin blog]
|
||||
* https://kotlin.link/[Awesome Kotlin]
|
||||
|
||||
|
||||
|
||||
=== Examples
|
||||
|
||||
The following Github projects offer examples that you can learn from and possibly even extend:
|
||||
|
|
@ -1016,6 +1085,8 @@ The following Github projects offer examples that you can learn from and possibl
|
|||
* https://github.com/sdeleuze/spring-kotlin-deepdive[spring-kotlin-deepdive]: A step-by-step migration guide for Boot 1.0 and Java to Boot 2.0 and Kotlin
|
||||
* https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-kotlin-samples/spring-cloud-gcp-kotlin-app-sample[spring-cloud-gcp-kotlin-app-sample]: Spring Boot with Google Cloud Platform Integrations
|
||||
|
||||
|
||||
|
||||
=== Issues
|
||||
|
||||
The following list categorizes the pending issues related to Spring and Kotlin support:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -30,11 +30,13 @@ import org.springframework.lang.Nullable;
|
|||
* {@link ParameterNameDiscoverer} implementation which uses Kotlin's reflection facilities
|
||||
* for introspecting parameter names.
|
||||
*
|
||||
* Compared to {@link StandardReflectionParameterNameDiscoverer}, it allows in addition to
|
||||
* <p>Compared to {@link StandardReflectionParameterNameDiscoverer}, it allows in addition to
|
||||
* determine interface parameter names without requiring Java 8 -parameters compiler flag.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 5.0
|
||||
* @see StandardReflectionParameterNameDiscoverer
|
||||
* @see DefaultParameterNameDiscoverer
|
||||
*/
|
||||
public class KotlinReflectionParameterNameDiscoverer implements ParameterNameDiscoverer {
|
||||
|
||||
|
|
|
|||
|
|
@ -47,12 +47,21 @@ import org.springframework.util.ClassUtils;
|
|||
* caches the ASM discovered information for each introspected Class, in a thread-safe
|
||||
* manner. It is recommended to reuse ParameterNameDiscoverer instances as far as possible.
|
||||
*
|
||||
* <p>This class is deprecated in the 6.0 generation and scheduled for removal in 6.1
|
||||
* since it is effectively superseded by {@link StandardReflectionParameterNameDiscoverer}.
|
||||
* For the time being, this discoverer logs a warning every time it actually inspects a
|
||||
* class file which is particularly useful for identifying remaining gaps in usage of
|
||||
* the standard "-parameters" compiler flag, and also unintended over-inspection of
|
||||
* e.g. JDK core library classes (which are not compiled with the "-parameters" flag).
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @author Costin Leau
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see StandardReflectionParameterNameDiscoverer
|
||||
* @see DefaultParameterNameDiscoverer
|
||||
* @deprecated as of 6.0.1, in favor of {@link StandardReflectionParameterNameDiscoverer}
|
||||
* (with the "-parameters" compiler flag)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -26,10 +26,15 @@ import org.springframework.lang.Nullable;
|
|||
* {@link ParameterNameDiscoverer} implementation which uses JDK 8's reflection facilities
|
||||
* for introspecting parameter names (based on the "-parameters" compiler flag).
|
||||
*
|
||||
* <p>This is a key element of {@link DefaultParameterNameDiscoverer} where it is being
|
||||
* combined with {@link KotlinReflectionParameterNameDiscoverer} if Kotlin is present.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0
|
||||
* @see java.lang.reflect.Method#getParameters()
|
||||
* @see java.lang.reflect.Parameter#getName()
|
||||
* @see KotlinReflectionParameterNameDiscoverer
|
||||
* @see DefaultParameterNameDiscoverer
|
||||
*/
|
||||
public class StandardReflectionParameterNameDiscoverer implements ParameterNameDiscoverer {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue