Skip to content

Commit 9d0f97f

Browse files
committed
Merge branch '5.1.x'
2 parents 4ca376e + 2a0a002 commit 9d0f97f

File tree

1 file changed

+78
-78
lines changed

1 file changed

+78
-78
lines changed

src/docs/asciidoc/languages/kotlin.adoc

+78-78
Original file line numberDiff line numberDiff line change
@@ -180,14 +180,27 @@ In Java, you can, for example, write the following:
180180
);
181181
----
182182

183-
In Kotlin, with reified type parameters and `GenericApplicationContext`
184-
Kotlin extensions, you can instead write the following:
183+
In Kotlin, with reified type parameters and `GenericApplicationContext` Kotlin extensions,
184+
you can instead write the following:
185185

186186
[source,kotlin,indent=0]
187187
----
188188
val context = GenericApplicationContext().apply {
189189
registerBean<Foo>()
190-
registerBean { Bar(it.getBean<Foo>()) }
190+
registerBean { Bar(it.getBean()) }
191+
}
192+
----
193+
====
194+
195+
If the class `Bar` has a single constructor, you can even just specify the bean class,
196+
the constructor parameters will be autowired by type:
197+
198+
====
199+
[source,kotlin,indent=0]
200+
----
201+
val context = GenericApplicationContext().apply {
202+
registerBean<Foo>()
203+
registerBean<Bar>()
191204
}
192205
----
193206

@@ -199,57 +212,38 @@ how beans are registered. The following example creates a `Play` profile:
199212

200213
[source,kotlin,indent=0]
201214
----
202-
fun beans() = beans {
203-
bean<UserHandler>()
204-
bean<Routes>()
205-
bean<WebHandler>("webHandler") {
206-
RouterFunctions.toWebHandler(
207-
ref<Routes>().router(),
208-
HandlerStrategies.builder().viewResolver(ref()).build()
209-
)
210-
}
211-
bean("messageSource") {
212-
ReloadableResourceBundleMessageSource().apply {
213-
setBasename("messages")
214-
setDefaultEncoding("UTF-8")
215+
val myBeans = beans {
216+
bean<Foo>()
217+
bean<Bar>()
218+
bean("bazBean") {
219+
Baz().apply {
220+
message = "Hello world"
215221
}
216222
}
217-
bean {
218-
val prefix = "classpath:/templates/"
219-
val suffix = ".mustache"
220-
val loader = MustacheResourceTemplateLoader(prefix, suffix)
221-
MustacheViewResolver(Mustache.compiler().withLoader(loader)).apply {
222-
setPrefix(prefix)
223-
setSuffix(suffix)
224-
}
225-
}
226-
profile("play") {
227-
bean<Play>()
223+
profile("foobar") {
224+
bean { FooBar(ref("bazBean")) }
228225
}
229226
}
230227
----
231228

232-
In the preceding example, `bean<Routes>()` uses autowiring by constructor, and `ref<Routes>()`
233-
is a shortcut for `applicationContext.getBean(Routes::class.java)`.
229+
NOTE: This DSL is programmatic, meaning it allows custom registration logic of beans
230+
through an `if` expression, a `for` loop, or any other Kotlin constructs.
234231

235232
You can then use this `beans()` function to register beans on the application context,
236233
as the following example shows:
237234

238235
[source,kotlin,indent=0]
239236
----
240237
val context = GenericApplicationContext().apply {
241-
beans().initialize(this)
238+
myBeans.initialize(this)
242239
refresh()
243240
}
244241
----
245242

246-
NOTE: This DSL is programmatic, meaning it allows custom registration logic of beans
247-
through an `if` expression, a `for` loop, or any other Kotlin constructs.
248243

249-
See https://github.com/sdeleuze/spring-kotlin-functional/blob/master/src/main/kotlin/functional/Beans.kt[spring-kotlin-functional beans declaration]
250-
for a concrete example.
244+
See https://github.com/sdeleuze/spring-kotlin-functional[spring-kotlin-functional beans declaration] for a concrete example.
251245

252-
NOTE: Spring Boot is based on Java configuration and
246+
NOTE: Spring Boot is based on JavaConfig and
253247
https://github.com/spring-projects/spring-boot/issues/8115[does not yet provide specific support for functional bean definition],
254248
but you can experimentally use functional bean definitions through Spring Boot's `ApplicationContextInitializer` support.
255249
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]
@@ -266,8 +260,8 @@ for more details and up-to-date information.
266260

267261
Spring Framework now comes with a
268262
{doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/-router-function-dsl/[Kotlin routing DSL]
269-
that lets you use the <<web-reactive#webflux-fn,WebFlux functional
270-
API>> to write clean and idiomatic Kotlin code, as the following example shows:
263+
that lets you use the <<web-reactive#webflux-fn,WebFlux functional API>> to write clean and idiomatic Kotlin code,
264+
as the following example shows:
271265

272266
[source,kotlin,indent=0]
273267
----
@@ -293,7 +287,7 @@ NOTE: This DSL is programmatic, meaning that it allows custom registration logic
293287
through an `if` expression, a `for` loop, or any other Kotlin constructs. That can be useful when you need to register routes
294288
depending on dynamic data (for example, from a database).
295289

296-
See https://github.com/mixitconf/mixit/tree/bad6b92bce6193f9b3f696af9d416c276501dbf1/src/main/kotlin/mixit/web/routes[MiXiT project routes]
290+
See https://github.com/mixitconf/mixit/tree/dafd5ccc92dfab6d9c306fcb60b28921a1ccbf79/src/main/kotlin/mixit/web/routes[MiXiT project routes]
297291
for a concrete example.
298292

299293

@@ -553,8 +547,42 @@ all HTTP methods will be matched, not only the `GET` one.
553547

554548
=== Testing
555549

556-
This section address testing with the combination of Kotlin and the Spring Framework.
550+
This section addresses testing with the combination of Kotlin and Spring Framework. The recommended testing framework
551+
is https://junit.org/junit5/[JUnit 5], as well as https://mockk.io/[Mockk] for mocking.
552+
553+
554+
==== Constructor injection
555+
556+
As described in the <<testing#testcontext-junit-jupiter-di#spring-web-reactive,dedicated section>>, JUnit 5 allows
557+
constructor injection of beans which is pretty useful with Kotlin in order to use `val` instead of `lateinit var `.
558+
559+
560+
====
561+
[source]
562+
----
563+
@SpringJUnitConfig(TestConfig::class)
564+
class OrderServiceIntegrationTests(@Autowired val orderService: OrderService,
565+
@Autowired val customerService: CustomerService) {
566+
567+
// tests that use the injected OrderService and CustomerService
568+
}
569+
----
570+
====
571+
572+
You can also use `@Autowired` at constructor level to autowire all parameters.
573+
574+
====
575+
[source]
576+
----
577+
@SpringJUnitConfig(TestConfig::class)
578+
class OrderServiceIntegrationTests @Autowired constructor(
579+
val orderService: OrderService,
580+
val customerService: CustomerService) {
557581
582+
// tests that use the injected OrderService and CustomerService
583+
}
584+
----
585+
====
558586

559587

560588
==== `PER_CLASS` Lifecycle
@@ -647,32 +675,27 @@ See also the related https://jira.spring.io/browse/SPR-16057[SPR-16057] issue.
647675
[[kotlin-getting-started]]
648676
== Getting Started
649677

650-
This section describes the fastest way to get started with a project that combines
651-
Kotlin and the Spring Framework.
678+
The easiest way to learn how to build a Spring application with Kotlin is to follow
679+
https://spring.io/guides/tutorials/spring-boot-kotlin/[the dedicated tutorial].
652680

653681

654-
655-
=== Using `start.spring.io`
682+
=== `start.spring.io`
656683

657684
The easiest way to start a new Spring Framework 5 project in Kotlin is to create a new Spring
658685
Boot 2 project on https://start.spring.io/#!language=kotlin[start.spring.io].
659686

660-
You can also create a standalone WebFlux project, as described in
661-
https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way[this blog post].
662-
663-
664687

665688
=== Choosing the Web Flavor
666689

667690
Spring Framework now comes with two different web stacks: <<web#mvc,Spring MVC>> and
668691
<<web-reactive#spring-web-reactive,Spring WebFlux>>.
669692

670693
Spring WebFlux is recommended if you want to create applications that will deal with latency,
671-
long-lived connections, o streaming scenarios or if you want to use the web functional
694+
long-lived connections, streaming scenarios or if you want to use the web functional
672695
Kotlin DSL.
673696

674697
For other use cases, especially if you are using blocking technologies such as JPA, Spring
675-
MVC and its annotation-based programming model is a perfectly valid and fully supported choice.
698+
MVC and its annotation-based programming model is the recommended choice.
676699

677700

678701

@@ -690,27 +713,6 @@ Kotlin and the Spring Framework:
690713
* https://kotlin.link/[Awesome Kotlin]
691714

692715

693-
694-
=== Tutorials
695-
696-
We recommend the following tutorials:
697-
698-
* https://spring.io/guides/tutorials/spring-boot-kotlin/[Building web applications with Spring Boot and Kotlin]
699-
* https://kotlinlang.org/docs/tutorials/spring-boot-restful.html[Creating a RESTful Web Service with Spring Boot]
700-
701-
702-
703-
=== Blog posts
704-
705-
The following blog posts provide further details:
706-
707-
* https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin[Developing Spring Boot applications with Kotlin]
708-
* 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]
709-
* https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0[Introducing Kotlin support in Spring Framework 5.0]
710-
* https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way[Spring Framework 5 Kotlin APIs, the functional way]
711-
712-
713-
714716
=== Examples
715717

716718
The following Github projects offer examples that you can learn from and possibly even extend:
@@ -721,6 +723,7 @@ The following Github projects offer examples that you can learn from and possibl
721723
* https://github.com/sdeleuze/spring-kotlin-fullstack[spring-kotlin-fullstack]: WebFlux Kotlin fullstack example with Kotlin2js for frontend instead of JavaScript or TypeScript
722724
* https://github.com/spring-petclinic/spring-petclinic-kotlin[spring-petclinic-kotlin]: Kotlin version of the Spring PetClinic Sample Application
723725
* 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
726+
* 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
724727

725728

726729

@@ -729,22 +732,19 @@ The following Github projects offer examples that you can learn from and possibl
729732
The following list categorizes the pending issues related to Spring and Kotlin support:
730733

731734
* Spring Framework
732-
** https://jira.spring.io/browse/SPR-16057[Unable to use WebTestClient with mock server in Kotlin]
733-
** https://jira.spring.io/browse/SPR-15942[Support null-safety at generics, varargs and array elements level]
734-
** https://jira.spring.io/browse/SPR-15413[Add support for Kotlin coroutines]
735+
** https://github.com/spring-projects/spring-framework/issues/20606[Unable to use WebTestClient with mock server in Kotlin]
736+
** https://github.com/spring-projects/spring-framework/issues/20496[Support null-safety at generics, varargs and array elements level]
737+
** https://github.com/spring-projects/spring-framework/issues/19975[Add support for Kotlin coroutines]
735738
* Spring Boot
736739
** https://github.com/spring-projects/spring-boot/issues/8762[Allow `@ConfigurationProperties` binding for immutable POJOs]
737-
** https://github.com/spring-projects/spring-boot/issues/1254[Allow `@ConfigurationProperties` binding on interfaces]
738740
** https://github.com/spring-projects/spring-boot/issues/8115[Expose the functional bean registration API via `SpringApplication`]
739741
** https://github.com/spring-projects/spring-boot/issues/10712[Add null-safety annotations on Spring Boot APIs]
740742
** https://github.com/spring-projects/spring-boot/issues/9486[Use Kotlin's bom to provide dependency management for Kotlin]
741743
* Kotlin
742744
** https://youtrack.jetbrains.com/issue/KT-6380[Parent issue for Spring Framework support]
743745
** https://youtrack.jetbrains.com/issue/KT-5464[Kotlin requires type inference where Java doesn't]
744-
** https://github.com/Kotlin/KEEP/issues/79[Better generics null-safety support]
745746
** https://youtrack.jetbrains.com/issue/KT-20283[Smart cast regression with open classes]
746747
** https://youtrack.jetbrains.com/issue/KT-14984[Impossible to pass not all SAM argument as function]
747-
** https://youtrack.jetbrains.com/issue/KT-19592[Apply JSR 305 meta-annotations to generic type parameters]
748-
** https://youtrack.jetbrains.com/issue/KT-18398[Provide a way for libraries to avoid mixing Kotlin 1.0 and 1.1 dependencies]
749748
** https://youtrack.jetbrains.com/issue/KT-15125[Support JSR 223 bindings directly via script variables]
750-
** https://youtrack.jetbrains.com/issue/KT-15467[Support all-open and no-arg compiler plugins in Kotlin Eclipse plugin]
749+
** https://youtrack.jetbrains.com/issue/KT-6653[Kotlin properties do not override Java-style getters and setters]
750+

0 commit comments

Comments
 (0)