SlideShare a Scribd company logo
1 of 75
Download to read offline
Why Spring Kotlin
Sébastien Deleuze
@sdeleuze
2
Most popular way to build web applications
+
Spring
Boot
3
Let’s see how far we can go with ...
Kotlin
+
Spring
Boot
4
5
Migrating a typical Boot application to Kotlin
https://github.com/sdeleuze/spring-kotlin-deepdive
6
Step 1
Kotlin
7
Step 2
Spring Boot 1 Spring Boot 2
based on Spring Framework 5
8
Step 3
Spring MVC Spring WebFlux
9
Step 4
Spring WebFlux
Functional API & Kotlin DSL
Spring WebFlux
@nnotations
From Java to Kotlin
Step 1 Kotlin
Step 2 Boot 2
Step 3 WebFlux
Step 4 Kotlin DSL & Functional API
11
https://start.spring.io/#!language=kotlin
12
Domain model
@Document
data class Article(
@Id val slug: String,
val title: String,
val headline: String,
val content: String,
@DBRef val author: User,
val addedAt: LocalDateTime = now())
@Document
data class User(
@Id val login: String,
val firstname: String,
val lastname: String,
val description: String? = null)
@Document
public class Article {
@Id
private String slug;
private String title;
private LocalDateTime addedAt;
private String headline;
private String content;
@DBRef
private User author;
public Article() {
}
public Article(String slug, String title, String
headline, String content, User author) {
this(slug, title, headline, content, author,
LocalDateTime.now());
}
public Article(String slug, String title, String
headline, String content, User author, LocalDateTime
addedAt) {
this.slug = slug;
this.title = title;
this.addedAt = addedAt;
this.headline = headline;
this.content = content;
this.author = author;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getTitle() {
return title;
}
13
Expressive test function names with backticks
class EmojTests {
@Test
fun `Why Spring ❤ Kotlin?`() {
println("Because I can use emoj in function names uD83DuDE09")
}
}
> Because I can use emoj in function names
14
@RestController
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@GetMapping("/user/{login}")
public User findOne(@PathVariable String login) {
return userRepository.findOne(login);
}
@GetMapping("/user")
public Iterable<User> findAll() {
return userRepository.findAll();
}
@PostMapping("/user")
public User save(@RequestBody User user) {
return userRepository.save(user);
}
}
Spring MVC controller written in Java
15
@RestController
class UserController(private val repo: UserRepository) {
@GetMapping("/user/{id}")
fun findOne(@PathVariable id: String) = repo.findOne(id)
@GetMapping("/user")
fun findAll() = repo.findAll()
@PostMapping("/user")
fun save(@RequestBody user: User) = repo.save(user)
}
Spring MVC controller written in Kotlin
16
Inferred type hints in IDEA
Settings
Editor
General
Appearance
Show parameter name hints
Select Kotlin
Check “Show function/property/local value return type hints”
kotlin-spring compiler plugin
Automatically open Spring annotated classes and methods
@SpringBootApplication
open class Application {
@Bean
open fun foo() = Foo()
@Bean
open fun bar(foo: Foo) = Bar(foo)
}
@SpringBootApplication
class Application {
@Bean
fun foo() = Foo()
@Bean
fun bar(foo: Foo) = Bar(foo)
}
Without kotlin-spring plugin With kotlin-spring plugin
17
From Java to Kotlin
Step 1 Kotlin
Step 2 Boot 2
Step 3 WebFlux
Step 4 Kotlin DSL & Functional API
Spring Kotlin
and officially supports it
Spring Framework 5
Spring Boot 2.0 (M7 available, GA early 2018)
Reactor Core 3.1
Spring Data Kay
20
Kotlin support out of the box
21
Kotlin support documentation
https://goo.gl/uwyjQn
Running Spring Boot 1 application with Kotlin
22
@SpringBootApplication
class Application
fun main(args: Array<String>) {
SpringApplication.run(Application::class.java, *args)
}
Running Spring Boot 2 application with Kotlin
23
@SpringBootApplication
class Application
fun main(args: Array<String>) {
runApplication<FooApplication>(*args)
}
Declaring additional beans
24
@SpringBootApplication
class Application {
@Bean
fun foo() = Foo()
@Bean
fun bar(foo: Foo) = Bar(foo)
}
fun main(args: Array<String>) {
runApplication<FooApplication>(*args)
}
Customizing SpringApplication
25
@SpringBootApplication
class Application {
@Bean
fun foo() = Foo()
@Bean
fun bar(foo: Foo) = Bar(foo)
}
fun main(args: Array<String>) {
runApplication<FooApplication>(*args) {
setBannerMode(OFF)
}
}
Array-like Kotlin extension for Model
operator fun Model.set(attributeName: String, attributeValue: Any) {
this.addAttribute(attributeName, attributeValue)
}
@GetMapping("/")
public String blog(Model model) {
model.addAttribute("title", "Blog");
model.addAttribute("articles", repository.findAll());
return "blog";
}
@GetMapping("/")
fun blog(model: Model): String {
model["title"] = "Blog"
model["articles"] = repository.findAll()
return "blog"
}
26
Reified type parameters Kotlin extension
inline fun <reified T: Any> RestOperations.exchange(url: String, method: HttpMethod,
requestEntity: HttpEntity<*>? = null) =
exchange(url, method, requestEntity, object : ParameterizedTypeReference<T>() {})
List<Article> list = restTemplate
.exchange("/api/article/", GET, null, new ParameterizedTypeReference<List<Article>>(){})
.getBody();
val list: List<Article> = restTemplate
.exchange("/api/article/", GET)
.getBody();
Goodbye type erasure, we are not going to miss you at all!
27
Null safety
28
Nothing enforced at type system
No check at compile time
NullPointerException at runtime
Optional only usable for return values
Default is non-null, ? suffix for nullable types
Full check at compile time
No NullPointerException !!!
Functional constructs on nullable values
By default, Kotlin interprets Java types as platform types (unknown nullability)
Null safety of Spring APIs
public interface RestOperations {
URI postForLocation(String url,
Object request,
Object ... uriVariables)
}
29
postForLocation(url: String!, request: Any!, varags uriVariables: Any!): URI!
Nullability annotations meta annotated with JSR 305 for generic tooling support
Null safety of Spring APIs
@NonNullApi
package org.springframework.web.client;
public interface RestOperations {
@Nullable
URI postForLocation(String url,
@Nullable Object request,
Object... uriVariables)
}
30
postForLocation(url: String, request: Any?, varargs uriVariables: Any): URI?
freeCompilerArgs =
["-Xjsr305=strict"]
+
31
@Controller // Mandatory Optional
class FooController(val foo: Foo, val bar: Bar?) {
@GetMapping("/") // Equivalent to @RequestParam(required=false)
fun foo(@RequestParam baz: String?) = ...
}
Leveraging Kotlin nullable information
To determine @RequestParam or @Autowired required attribute
@ConfigurationProperties
@ConfigurationProperties("foo")
data class FooProperties(
var baseUri: String? = null,
var admin = Credentials()) {
data class Credential(
var username: String? = null,
var password: String? = null)
}
One of the remaining pain points in Kotlin
33
JUnit 5 supports non-static @BeforeAll @AfterAll
class IntegrationTests {
private val application = Application(8181)
private val client = WebClient.create("http://localhost:8181")
@BeforeAll
fun beforeAll() { application.start() }
@Test
fun test1() { // ... }
@Test
fun test2() { // ... }
@AfterAll
fun afterAll() { application.stop() }
}
With “per class” lifecycle defined via junit-platform.properties or @TestInstance
34
JUnit 5 supports constructor based injection
@ExtendWith(SpringExtension::class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
class HtmlTests(@Autowired val restTemplate: TestRestTemplate) {
@Test
fun test1() { // ... }
@Test
fun test2() { // ... }
}
Allows to use val instead of lateinit var in tests
35
class SimpleTests {
@Nested
@DisplayName("a calculator")
inner class Calculator {
val calculator = SampleCalculator()
@Test
fun `should return the result of adding the first number to the second number`() {
val sum = calculator.sum(2, 4)
assertEquals(6, sum)
}
@Test
fun `should return the result of subtracting the second number from the first number`() {
val subtract = calculator.subtract(4, 2)
assertEquals(2, subtract)
}
}
}
Specification-like tests with Kotlin and JUnit 5
From Java to Kotlin
Step 1 Kotlin
Step 2 Boot 2
Step 3 WebFlux
Step 4 Kotlin DSL & Functional API
Spring Framework 5 introduces
a new web stack
Spring MVC
Blocking
Servlet
Spring WebFlux
Non-blocking
Reactive Streams
38
∞
Streaming
Scalability
Latency
∞
40
RxJava
?
WebFlux supports various non-blocking API
CompletableFuture
Flow.Publisher
Reactor Akka
41
Let’s focus on Reactor for now
RxJavaCompletableFuture
Flow.Publisher
Reactor Akka
?
42
Mono is a reactive type for 0..1 element
43
Flux is for reactive collection and stream
44
@RestController
class ReactiveUserController(val repository: ReactiveUserRepository) {
@GetMapping("/user/{id}")
fun findOne(@PathVariable id: String): Mono<User>
= repository.findOne(id)
@GetMapping("/user")
fun findAll(): Flux<User>
= repository.findAll()
@PostMapping("/user")
fun save(@RequestBody user: Mono<User>): Mono<Void>
= repository.save(user)
}
interface ReactiveUserRepository {
fun findOne(id: String): Mono<User>
fun findAll(): Flux<User>
fun save(user: Mono<User>): Mono<Void>
}
Spring WebFlux with annotations
Spring Data Kay provides
Reactive support for
MongoDB, Redis, Cassandra
and Couchbase
45
val location = "Lyon, France"
mainService.fetchWeather(location)
.timeout(Duration.ofSeconds(2))
.doOnError { logger.error(it.getMessage()) }
.onErrorResume { backupService.fetchWeather(location) }
.map { "Weather in ${it.getLocation()} is ${it.getDescription()}" }
.subscribe { logger.info(it) }
fun fetchWeather(city: String): Mono<Weather>
Reactive APIs = functional programming
Reactor Kotlin extensions
Java Kotlin with extensions
Mono.just("foo") "foo".toMono()
Flux.fromIterable(list) list.toFlux()
Mono.error(new RuntimeException()) RuntimeException().toMono()
flux.ofType(User.class) flux.ofType<User>()
StepVerifier.create(flux).verifyComplete() flux.test().verifyComplete()
MathFlux.averageDouble(flux) flux.average()
From Java to Kotlin
Step 1 Kotlin
Step 2 Boot 2
Step 3 WebFlux
Step 4 Kotlin DSL & Functional API
48
val router = router {
val users = …
accept(TEXT_HTML).nest {
"/" { ok().render("index") }
"/sse" { ok().render("sse") }
"/users" {
ok().render("users", mapOf("users" to users.map { it.toDto() }))
}
}
("/api/users" and accept(APPLICATION_JSON)) {
ok().body(users)
}
("/api/users" and accept(TEXT_EVENT_STREAM)) {
ok().bodyToServerSentEvents(users.repeat().delayElements(ofMillis(100)))
}
}
WebFlux functional API with Kotlin DSL
49
@SpringBootApplication
class Application {
@Bean
fun router(htmlHandler: HtmlHandler, userHandler: UserHandler, articleHandler: ArticleHandler) = router {
accept(APPLICATION_JSON).nest {
"/api/user".nest {
GET("/", userHandler::findAll)
GET("/{login}", userHandler::findOne)
}
"/api/article".nest {
GET("/", articleHandler::findAll)
GET("/{slug}", articleHandler::findOne)
POST("/", articleHandler::save)
DELETE("/{slug}", articleHandler::delete)
}
}
(GET("/api/article/notifications") and accept(TEXT_EVENT_STREAM)).invoke(articleHandler::notifications)
accept(TEXT_HTML).nest {
GET("/", htmlHandler::blog)
(GET("/{slug}") and !GET("/favicon.ico")).invoke(htmlHandler::article)
}
}
}
Functional router within Boot
@Component
class HtmlHandler(private val userRepository: UserRepository,
private val converter: MarkdownConverter) {
fun blog(req: ServerRequest) = ok().render("blog", mapOf(
"title" to "Blog",
"articles" to articleRepository.findAll()
.flatMap { it.toDto(userRepository, converter) } ))
}
@Component
class ArticleHandler(private val articleRepository: ArticleRepository,
private val articleEventRepository: ArticleEventRepository) {
fun findAll(req: ServerRequest) =
ok().body(articleRepository.findAll())
fun notifications(req: ServerRequest) =
ok().bodyToServerSentEvents(articleEventRepository.findWithTailableCursorBy())
}
50
Functional handlers within Boot
Under construction ...
Fixing remaining pain points
Coroutines
Functional bean definition
Multi-platform
Immutable non-nullable @ConfigurationProperties
@ConfigurationProperties("foo")
data class FooProperties(
val baseUri: String,
val admin: Credential) {
data class Credential(
val username: String,
val password: String)
}
Boot 2.x ?
See issue #8762 for more details
@ConfigurationProperties("foo")
data class FooProperties(
var baseUri: String? = null,
var admin = Credentials()) {
data class Credential(
var username: String? = null,
var password: String? = null)
}
Currently
N
ot yet available
WebTestClient
Unusable in Kotlin due to a type inference issue, see KT-5464
otlin 1.3
For now, please use:
- WebClient in Kotlin
- WebTestClient in Java
Under construction ...
Fixing remaining pain points
Coroutines
Boot + functional bean DSL
Multi-platform
55
Kotlin Coroutines
RxJavaCompletableFuture
Flow.Publisher
Reactor Akka
Coroutines
Experimental
Spring & Kotlin Coroutines
56
● Coroutines are Kotlin lightweight threads
● Allows non-blocking imperative code
● Less powerful than Reactive API (backpressure, streaming, operators, etc.)
● kotlinx.coroutines: Reactive Streams and Reactor support
● spring-kotlin-coroutine: experimental Spring support (community driven)
● Warning
○ Coroutine are still experimental
○ No official Spring support yet, see SPR-15413
○ Ongoing evaluation of performances and back-pressure interoperability
Experim
ental
https://github.com/konrad-kaminski/spring-kotlin-coroutine
Reactive Coroutines interop
57
Operation Reactive Coroutines
Async value fun foo(): Mono<T> suspend fun foo(): T?
Async collection fun foo(): Mono<List<T>> suspend fun foo(): List<T>
Stream fun foo(): Flux<T> suspend fun foo(): ReceiveChannel<T>
Async completion fun foo(): Mono<Void> suspend fun foo()
58
@RestController
class CoroutineUserController(val repository: CoroutineUserRepository) {
@GetMapping("/user/{id}")
suspend fun findOne(@PathVariable id: String): User
= repository.findOne(id)
@GetMapping("/user")
suspend fun findAll(): List<User>
= repository.findAll()
@PostMapping("/user")
suspend fun save(@RequestBody user: User)
= repository.save(user)
}
interface CoroutineUserRepository {
suspend fun findOne(id: String): User
suspend fun findAll(): List<User>
suspend fun save(user: User)
}
Spring WebFlux with Coroutines Experim
ental
https://github.com/sdeleuze/spring-kotlin-deepdive/tree/step3-coroutine
Under construction ...
Fixing remaining pain points
Coroutines
Boot + functional bean DSL
Multi-platform
Spring Framework 5 introduces
Functional bean definition
Very efficient, no reflection, no CGLIB proxy
Lambdas instead of annotations
Both declarative and programmatic
61
Functional bean definition Kotlin DSL
val databaseContext =
beans {
bean<ArticleEventListener>()
bean<ArticleEventRepository>()
bean<ArticleRepository>()
bean<UserRepository>()
environment( { !activeProfiles.contains("cloud") } ) {
bean {
InitializingBean {
initializeDatabase(ref(), ref(), ref())
}
}
}
}
fun initializeDatabase(ops: MongoOperations,
userRepository: UserRepository,
articleRepository: ArticleRepository) { // ... }
62
Beans + router DSL fit well together
val context =
beans {
bean {
val userHandler = ref<UserHandler>()
router {
accept(APPLICATION_JSON).nest {
"/api/user".nest {
GET("/", userHandler::findAll)
GET("/{login}", userHandler::findOne)
}
}
}
bean { Mustache.compiler().escapeHTML(false).withLoader(ref()) }
bean<HtmlHandler>()
bean<ArticleHandler>()
bean<UserHandler>()
bean<MarkdownConverter>()
}
63
Bean DSL is extensible and composable !
webfluxApplication(Server.NETTY) { // or TOMCAT
// group routers
routes {
router { routerApi(ref()) }
router(routerStatic())
}
router { routerHtml(ref(), ref()) }
// group beans
beans {
bean<UserHandler>()
bean<Baz>() // Primary constructor injection
}
bean<Bar>()
mustacheTemplate()
profile("foo") {
bean<Foo>()
}
}
See https://github.com/tgirard12/spring-webflux-kotlin-dsl
POC
Functional bean definition with Spring Boot
64
@SpringBootApplication
class Application
fun main(args: Array<String>) {
runApplication<FooApplication>(*args) {
addInitializers(databaseContext, webContext)
}
}
This nice syntax currently works only for running the application, not tests
Functional bean definition with Spring Boot
65
class ContextInitializer : ApplicationContextInitializer<GenericApplicationContext> {
override fun initialize(context: GenericApplicationContext) {
databaseContext.initialize(context)
webContext.initialize(context)
}
}
context.initializer.classes=io.spring.deepdive.ContextInitializer
This more verbose one works for running both application and tests
Functional bean definition with Spring Boot
66
Come discussing next steps with us
Under construction ...
Fixing remaining pain points
Coroutines
Boot + functional bean DSL
Multi-platform
Kotlin is multi-platform
Kotlin/JVM: JVM and Android
Kotlin/JS: transpile to JavaScript
Kotlin/Native: run without any VM (LLVM toolchain)
69
Kotlin for frontend today with Kotlin/JS
70
Original JavaScript code
if (Notification.permission === "granted") {
Notification.requestPermission().then(function(result) {
console.log(result);
});
}
let eventSource = new EventSource("/api/article/notifications");
eventSource.addEventListener("message", function(e) {
let article = JSON.parse(e.data);
let notification = new Notification(article.title);
notification.onclick = function() {
window.location.href = "/" + article.slug;
};
});
71
Kotlin to Javascript
data class Article(val slug: String, val title: String)
fun main(args: Array<String>) {
if (Notification.permission == NotificationPermission.GRANTED) {
Notification.requestPermission().then { console.log(it) }
}
EventSource("/api/article/notifications").addEventListener("message", {
val article = JSON.parse<Article>(it.data());
Notification(article.title).addEventListener("click", {
window.location.href = "/${article.slug}"
})
})
}
fun Event.data() = (this as MessageEvent).data as String // See KT-20743
Type safety, null safety, only 10 Kbytes with Dead Code Elimination tool
72
Kotlin for frontend tomorrow with WebAssembly
Read “An Abridged Cartoon Introduction To WebAssembly” by Lin Clark for more details
https://goo.gl/I0kQsC
A sandboxed native platform for the Web (W3C, no plugin involved)
73
Compiling Kotlin to WebAssembly
+
➔ Kotlin supports WebAssembly via Kotlin/Native
➔ Better compilation target than JS: bytecode, performance, memory
➔ DOM API and GC are coming ...
➔ A Kotlin/Native Frontend ecosystem could arise
Experim
ental
Kotlin 1.2 allows sharing code
between platforms
Multi-platform data types and serialization are coming
Thanks!
https://speakerdeck.com/sdeleuze/why-spring-loves-kotlin
Follow me on @sdeleuze for fresh Spring + Kotlin news
https://github.com/mixitconf/mixit
https://github.com/sdeleuze/spring-kotlin-fullstack
https://github.com/sdeleuze/spring-kotlin-deepdive
https://github.com/sdeleuze/spring-kotlin-functional

More Related Content

What's hot

Dependency Injection with CDI in 15 minutes
Dependency Injection with CDI in 15 minutesDependency Injection with CDI in 15 minutes
Dependency Injection with CDI in 15 minutesAntonio Goncalves
 
Java Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to MissJava Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to MissAndres Almiray
 
JavaScript in 2016
JavaScript in 2016JavaScript in 2016
JavaScript in 2016Codemotion
 
Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Ray Ploski
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confFabio Collini
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorBartosz Kosarzycki
 
Kotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersKotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersBartosz Kosarzycki
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsBartosz Kosarzycki
 
Lombok Features
Lombok FeaturesLombok Features
Lombok Features文峰 眭
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingCodemotion
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyDavid Gómez García
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code EffectivelyAndres Almiray
 
Modern Java Workshop
Modern Java WorkshopModern Java Workshop
Modern Java WorkshopSimon Ritter
 
Reactive Programming with JavaScript
Reactive Programming with JavaScriptReactive Programming with JavaScript
Reactive Programming with JavaScriptCodemotion
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
Con-FESS 2015 - Having Fun With Javassist
Con-FESS 2015 - Having Fun With JavassistCon-FESS 2015 - Having Fun With Javassist
Con-FESS 2015 - Having Fun With JavassistAnton Arhipov
 
JDD 2016 - Grzegorz Rozniecki - Java 8 What Could Possibly Go Wrong
JDD 2016 - Grzegorz Rozniecki - Java 8 What Could Possibly Go WrongJDD 2016 - Grzegorz Rozniecki - Java 8 What Could Possibly Go Wrong
JDD 2016 - Grzegorz Rozniecki - Java 8 What Could Possibly Go WrongPROIDEA
 
Geecon - Improve your Android-fu with Kotlin
Geecon - Improve your Android-fu with KotlinGeecon - Improve your Android-fu with Kotlin
Geecon - Improve your Android-fu with KotlinNicolas Fränkel
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMMario Fusco
 

What's hot (20)

Dependency Injection with CDI in 15 minutes
Dependency Injection with CDI in 15 minutesDependency Injection with CDI in 15 minutes
Dependency Injection with CDI in 15 minutes
 
Java Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to MissJava Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to Miss
 
JavaScript in 2016
JavaScript in 2016JavaScript in 2016
JavaScript in 2016
 
Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community conf
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processor
 
Kotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developersKotlin advanced - language reference for android developers
Kotlin advanced - language reference for android developers
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
 
Lombok Features
Lombok FeaturesLombok Features
Lombok Features
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results Asynchrhonously
 
Ad java prac sol set
Ad java prac sol setAd java prac sol set
Ad java prac sol set
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code Effectively
 
Modern Java Workshop
Modern Java WorkshopModern Java Workshop
Modern Java Workshop
 
Reactive Programming with JavaScript
Reactive Programming with JavaScriptReactive Programming with JavaScript
Reactive Programming with JavaScript
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Con-FESS 2015 - Having Fun With Javassist
Con-FESS 2015 - Having Fun With JavassistCon-FESS 2015 - Having Fun With Javassist
Con-FESS 2015 - Having Fun With Javassist
 
JDD 2016 - Grzegorz Rozniecki - Java 8 What Could Possibly Go Wrong
JDD 2016 - Grzegorz Rozniecki - Java 8 What Could Possibly Go WrongJDD 2016 - Grzegorz Rozniecki - Java 8 What Could Possibly Go Wrong
JDD 2016 - Grzegorz Rozniecki - Java 8 What Could Possibly Go Wrong
 
Geecon - Improve your Android-fu with Kotlin
Geecon - Improve your Android-fu with KotlinGeecon - Improve your Android-fu with Kotlin
Geecon - Improve your Android-fu with Kotlin
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
 

Similar to Why Spring <3 Kotlin

K is for Kotlin
K is for KotlinK is for Kotlin
K is for KotlinTechMagic
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Kotlin Advanced - language reference for Android developers
Kotlin Advanced - language reference for Android developers Kotlin Advanced - language reference for Android developers
Kotlin Advanced - language reference for Android developers STX Next
 
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехБоремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехСбертех | SberTech
 
Kotlin for Android Developers - 3
Kotlin for Android Developers - 3Kotlin for Android Developers - 3
Kotlin for Android Developers - 3Mohamed Nabil, MSc.
 
Building Mobile Apps with Android
Building Mobile Apps with AndroidBuilding Mobile Apps with Android
Building Mobile Apps with AndroidKurt Renzo Acosta
 
Rapid Web API development with Kotlin and Ktor
Rapid Web API development with Kotlin and KtorRapid Web API development with Kotlin and Ktor
Rapid Web API development with Kotlin and KtorTrayan Iliev
 
Appium Automation with Kotlin
Appium Automation with KotlinAppium Automation with Kotlin
Appium Automation with KotlinRapidValue
 
Practical tips for building apps with kotlin
Practical tips for building apps with kotlinPractical tips for building apps with kotlin
Practical tips for building apps with kotlinAdit Lal
 
Save time with kotlin in android development
Save time with kotlin in android developmentSave time with kotlin in android development
Save time with kotlin in android developmentAdit Lal
 
Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel GeheugenDevnology
 
ASP.Net 5 and C# 6
ASP.Net 5 and C# 6ASP.Net 5 and C# 6
ASP.Net 5 and C# 6Andy Butland
 
Testing in android
Testing in androidTesting in android
Testing in androidjtrindade
 
From Java to Kotlin - The first month in practice
From Java to Kotlin - The first month in practiceFrom Java to Kotlin - The first month in practice
From Java to Kotlin - The first month in practiceStefanTomm
 
Effective Java. By materials of Josch Bloch's book
Effective Java. By materials of Josch Bloch's bookEffective Java. By materials of Josch Bloch's book
Effective Java. By materials of Josch Bloch's bookRoman Tsypuk
 
Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Julien Truffaut
 

Similar to Why Spring <3 Kotlin (20)

K is for Kotlin
K is for KotlinK is for Kotlin
K is for Kotlin
 
Spring boot
Spring boot Spring boot
Spring boot
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Kotlin Advanced - language reference for Android developers
Kotlin Advanced - language reference for Android developers Kotlin Advanced - language reference for Android developers
Kotlin Advanced - language reference for Android developers
 
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехБоремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
 
Kotlin for Android Developers - 3
Kotlin for Android Developers - 3Kotlin for Android Developers - 3
Kotlin for Android Developers - 3
 
Building Mobile Apps with Android
Building Mobile Apps with AndroidBuilding Mobile Apps with Android
Building Mobile Apps with Android
 
Rapid Web API development with Kotlin and Ktor
Rapid Web API development with Kotlin and KtorRapid Web API development with Kotlin and Ktor
Rapid Web API development with Kotlin and Ktor
 
Appium Automation with Kotlin
Appium Automation with KotlinAppium Automation with Kotlin
Appium Automation with Kotlin
 
Practical tips for building apps with kotlin
Practical tips for building apps with kotlinPractical tips for building apps with kotlin
Practical tips for building apps with kotlin
 
Save time with kotlin in android development
Save time with kotlin in android developmentSave time with kotlin in android development
Save time with kotlin in android development
 
Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel Geheugen
 
ASP.Net 5 and C# 6
ASP.Net 5 and C# 6ASP.Net 5 and C# 6
ASP.Net 5 and C# 6
 
Java vs kotlin
Java vs kotlinJava vs kotlin
Java vs kotlin
 
Testing in android
Testing in androidTesting in android
Testing in android
 
From Java to Kotlin - The first month in practice
From Java to Kotlin - The first month in practiceFrom Java to Kotlin - The first month in practice
From Java to Kotlin - The first month in practice
 
Effective Java. By materials of Josch Bloch's book
Effective Java. By materials of Josch Bloch's bookEffective Java. By materials of Josch Bloch's book
Effective Java. By materials of Josch Bloch's book
 
Kotlin Generation
Kotlin GenerationKotlin Generation
Kotlin Generation
 
Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!
 
Thread
ThreadThread
Thread
 

More from VMware Tanzu

What AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItWhat AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItVMware Tanzu
 
Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023VMware Tanzu
 
Enhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleEnhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleVMware Tanzu
 
Spring Update | July 2023
Spring Update | July 2023Spring Update | July 2023
Spring Update | July 2023VMware Tanzu
 
Platforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductPlatforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductVMware Tanzu
 
Building Cloud Ready Apps
Building Cloud Ready AppsBuilding Cloud Ready Apps
Building Cloud Ready AppsVMware Tanzu
 
Spring Boot 3 And Beyond
Spring Boot 3 And BeyondSpring Boot 3 And Beyond
Spring Boot 3 And BeyondVMware Tanzu
 
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfSpring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfVMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023VMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023VMware Tanzu
 
tanzu_developer_connect.pptx
tanzu_developer_connect.pptxtanzu_developer_connect.pptx
tanzu_developer_connect.pptxVMware Tanzu
 
Tanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchTanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchVMware Tanzu
 
Tanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishTanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishVMware Tanzu
 
Virtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVirtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVMware Tanzu
 
Tanzu Developer Connect - French
Tanzu Developer Connect - FrenchTanzu Developer Connect - French
Tanzu Developer Connect - FrenchVMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023VMware Tanzu
 
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootSpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootVMware Tanzu
 
SpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerSpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerVMware Tanzu
 
SpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeSpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeVMware Tanzu
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsVMware Tanzu
 

More from VMware Tanzu (20)

What AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItWhat AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About It
 
Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023
 
Enhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleEnhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at Scale
 
Spring Update | July 2023
Spring Update | July 2023Spring Update | July 2023
Spring Update | July 2023
 
Platforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductPlatforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a Product
 
Building Cloud Ready Apps
Building Cloud Ready AppsBuilding Cloud Ready Apps
Building Cloud Ready Apps
 
Spring Boot 3 And Beyond
Spring Boot 3 And BeyondSpring Boot 3 And Beyond
Spring Boot 3 And Beyond
 
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfSpring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
 
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
 
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
 
tanzu_developer_connect.pptx
tanzu_developer_connect.pptxtanzu_developer_connect.pptx
tanzu_developer_connect.pptx
 
Tanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchTanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - French
 
Tanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishTanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - English
 
Virtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVirtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - English
 
Tanzu Developer Connect - French
Tanzu Developer Connect - FrenchTanzu Developer Connect - French
Tanzu Developer Connect - French
 
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
 
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootSpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
 
SpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerSpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software Engineer
 
SpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeSpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs Practice
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
 

Recently uploaded

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 

Recently uploaded (20)

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 

Why Spring <3 Kotlin

  • 1. Why Spring Kotlin Sébastien Deleuze @sdeleuze
  • 2. 2 Most popular way to build web applications + Spring Boot
  • 3. 3 Let’s see how far we can go with ... Kotlin + Spring Boot
  • 4. 4
  • 5. 5 Migrating a typical Boot application to Kotlin https://github.com/sdeleuze/spring-kotlin-deepdive
  • 7. 7 Step 2 Spring Boot 1 Spring Boot 2 based on Spring Framework 5
  • 8. 8 Step 3 Spring MVC Spring WebFlux
  • 9. 9 Step 4 Spring WebFlux Functional API & Kotlin DSL Spring WebFlux @nnotations
  • 10. From Java to Kotlin Step 1 Kotlin Step 2 Boot 2 Step 3 WebFlux Step 4 Kotlin DSL & Functional API
  • 12. 12 Domain model @Document data class Article( @Id val slug: String, val title: String, val headline: String, val content: String, @DBRef val author: User, val addedAt: LocalDateTime = now()) @Document data class User( @Id val login: String, val firstname: String, val lastname: String, val description: String? = null) @Document public class Article { @Id private String slug; private String title; private LocalDateTime addedAt; private String headline; private String content; @DBRef private User author; public Article() { } public Article(String slug, String title, String headline, String content, User author) { this(slug, title, headline, content, author, LocalDateTime.now()); } public Article(String slug, String title, String headline, String content, User author, LocalDateTime addedAt) { this.slug = slug; this.title = title; this.addedAt = addedAt; this.headline = headline; this.content = content; this.author = author; } public String getSlug() { return slug; } public void setSlug(String slug) { this.slug = slug; } public String getTitle() { return title; }
  • 13. 13 Expressive test function names with backticks class EmojTests { @Test fun `Why Spring ❤ Kotlin?`() { println("Because I can use emoj in function names uD83DuDE09") } } > Because I can use emoj in function names
  • 14. 14 @RestController public class UserController { private final UserRepository userRepository; public UserController(UserRepository userRepository) { this.userRepository = userRepository; } @GetMapping("/user/{login}") public User findOne(@PathVariable String login) { return userRepository.findOne(login); } @GetMapping("/user") public Iterable<User> findAll() { return userRepository.findAll(); } @PostMapping("/user") public User save(@RequestBody User user) { return userRepository.save(user); } } Spring MVC controller written in Java
  • 15. 15 @RestController class UserController(private val repo: UserRepository) { @GetMapping("/user/{id}") fun findOne(@PathVariable id: String) = repo.findOne(id) @GetMapping("/user") fun findAll() = repo.findAll() @PostMapping("/user") fun save(@RequestBody user: User) = repo.save(user) } Spring MVC controller written in Kotlin
  • 16. 16 Inferred type hints in IDEA Settings Editor General Appearance Show parameter name hints Select Kotlin Check “Show function/property/local value return type hints”
  • 17. kotlin-spring compiler plugin Automatically open Spring annotated classes and methods @SpringBootApplication open class Application { @Bean open fun foo() = Foo() @Bean open fun bar(foo: Foo) = Bar(foo) } @SpringBootApplication class Application { @Bean fun foo() = Foo() @Bean fun bar(foo: Foo) = Bar(foo) } Without kotlin-spring plugin With kotlin-spring plugin 17
  • 18. From Java to Kotlin Step 1 Kotlin Step 2 Boot 2 Step 3 WebFlux Step 4 Kotlin DSL & Functional API
  • 19. Spring Kotlin and officially supports it Spring Framework 5 Spring Boot 2.0 (M7 available, GA early 2018) Reactor Core 3.1 Spring Data Kay
  • 20. 20 Kotlin support out of the box
  • 22. Running Spring Boot 1 application with Kotlin 22 @SpringBootApplication class Application fun main(args: Array<String>) { SpringApplication.run(Application::class.java, *args) }
  • 23. Running Spring Boot 2 application with Kotlin 23 @SpringBootApplication class Application fun main(args: Array<String>) { runApplication<FooApplication>(*args) }
  • 24. Declaring additional beans 24 @SpringBootApplication class Application { @Bean fun foo() = Foo() @Bean fun bar(foo: Foo) = Bar(foo) } fun main(args: Array<String>) { runApplication<FooApplication>(*args) }
  • 25. Customizing SpringApplication 25 @SpringBootApplication class Application { @Bean fun foo() = Foo() @Bean fun bar(foo: Foo) = Bar(foo) } fun main(args: Array<String>) { runApplication<FooApplication>(*args) { setBannerMode(OFF) } }
  • 26. Array-like Kotlin extension for Model operator fun Model.set(attributeName: String, attributeValue: Any) { this.addAttribute(attributeName, attributeValue) } @GetMapping("/") public String blog(Model model) { model.addAttribute("title", "Blog"); model.addAttribute("articles", repository.findAll()); return "blog"; } @GetMapping("/") fun blog(model: Model): String { model["title"] = "Blog" model["articles"] = repository.findAll() return "blog" } 26
  • 27. Reified type parameters Kotlin extension inline fun <reified T: Any> RestOperations.exchange(url: String, method: HttpMethod, requestEntity: HttpEntity<*>? = null) = exchange(url, method, requestEntity, object : ParameterizedTypeReference<T>() {}) List<Article> list = restTemplate .exchange("/api/article/", GET, null, new ParameterizedTypeReference<List<Article>>(){}) .getBody(); val list: List<Article> = restTemplate .exchange("/api/article/", GET) .getBody(); Goodbye type erasure, we are not going to miss you at all! 27
  • 28. Null safety 28 Nothing enforced at type system No check at compile time NullPointerException at runtime Optional only usable for return values Default is non-null, ? suffix for nullable types Full check at compile time No NullPointerException !!! Functional constructs on nullable values
  • 29. By default, Kotlin interprets Java types as platform types (unknown nullability) Null safety of Spring APIs public interface RestOperations { URI postForLocation(String url, Object request, Object ... uriVariables) } 29 postForLocation(url: String!, request: Any!, varags uriVariables: Any!): URI!
  • 30. Nullability annotations meta annotated with JSR 305 for generic tooling support Null safety of Spring APIs @NonNullApi package org.springframework.web.client; public interface RestOperations { @Nullable URI postForLocation(String url, @Nullable Object request, Object... uriVariables) } 30 postForLocation(url: String, request: Any?, varargs uriVariables: Any): URI? freeCompilerArgs = ["-Xjsr305=strict"] +
  • 31. 31 @Controller // Mandatory Optional class FooController(val foo: Foo, val bar: Bar?) { @GetMapping("/") // Equivalent to @RequestParam(required=false) fun foo(@RequestParam baz: String?) = ... } Leveraging Kotlin nullable information To determine @RequestParam or @Autowired required attribute
  • 32. @ConfigurationProperties @ConfigurationProperties("foo") data class FooProperties( var baseUri: String? = null, var admin = Credentials()) { data class Credential( var username: String? = null, var password: String? = null) } One of the remaining pain points in Kotlin
  • 33. 33 JUnit 5 supports non-static @BeforeAll @AfterAll class IntegrationTests { private val application = Application(8181) private val client = WebClient.create("http://localhost:8181") @BeforeAll fun beforeAll() { application.start() } @Test fun test1() { // ... } @Test fun test2() { // ... } @AfterAll fun afterAll() { application.stop() } } With “per class” lifecycle defined via junit-platform.properties or @TestInstance
  • 34. 34 JUnit 5 supports constructor based injection @ExtendWith(SpringExtension::class) @SpringBootTest(webEnvironment = RANDOM_PORT) class HtmlTests(@Autowired val restTemplate: TestRestTemplate) { @Test fun test1() { // ... } @Test fun test2() { // ... } } Allows to use val instead of lateinit var in tests
  • 35. 35 class SimpleTests { @Nested @DisplayName("a calculator") inner class Calculator { val calculator = SampleCalculator() @Test fun `should return the result of adding the first number to the second number`() { val sum = calculator.sum(2, 4) assertEquals(6, sum) } @Test fun `should return the result of subtracting the second number from the first number`() { val subtract = calculator.subtract(4, 2) assertEquals(2, subtract) } } } Specification-like tests with Kotlin and JUnit 5
  • 36. From Java to Kotlin Step 1 Kotlin Step 2 Boot 2 Step 3 WebFlux Step 4 Kotlin DSL & Functional API
  • 37. Spring Framework 5 introduces a new web stack Spring MVC Blocking Servlet Spring WebFlux Non-blocking Reactive Streams
  • 39.
  • 40. 40 RxJava ? WebFlux supports various non-blocking API CompletableFuture Flow.Publisher Reactor Akka
  • 41. 41 Let’s focus on Reactor for now RxJavaCompletableFuture Flow.Publisher Reactor Akka ?
  • 42. 42 Mono is a reactive type for 0..1 element
  • 43. 43 Flux is for reactive collection and stream
  • 44. 44 @RestController class ReactiveUserController(val repository: ReactiveUserRepository) { @GetMapping("/user/{id}") fun findOne(@PathVariable id: String): Mono<User> = repository.findOne(id) @GetMapping("/user") fun findAll(): Flux<User> = repository.findAll() @PostMapping("/user") fun save(@RequestBody user: Mono<User>): Mono<Void> = repository.save(user) } interface ReactiveUserRepository { fun findOne(id: String): Mono<User> fun findAll(): Flux<User> fun save(user: Mono<User>): Mono<Void> } Spring WebFlux with annotations Spring Data Kay provides Reactive support for MongoDB, Redis, Cassandra and Couchbase
  • 45. 45 val location = "Lyon, France" mainService.fetchWeather(location) .timeout(Duration.ofSeconds(2)) .doOnError { logger.error(it.getMessage()) } .onErrorResume { backupService.fetchWeather(location) } .map { "Weather in ${it.getLocation()} is ${it.getDescription()}" } .subscribe { logger.info(it) } fun fetchWeather(city: String): Mono<Weather> Reactive APIs = functional programming
  • 46. Reactor Kotlin extensions Java Kotlin with extensions Mono.just("foo") "foo".toMono() Flux.fromIterable(list) list.toFlux() Mono.error(new RuntimeException()) RuntimeException().toMono() flux.ofType(User.class) flux.ofType<User>() StepVerifier.create(flux).verifyComplete() flux.test().verifyComplete() MathFlux.averageDouble(flux) flux.average()
  • 47. From Java to Kotlin Step 1 Kotlin Step 2 Boot 2 Step 3 WebFlux Step 4 Kotlin DSL & Functional API
  • 48. 48 val router = router { val users = … accept(TEXT_HTML).nest { "/" { ok().render("index") } "/sse" { ok().render("sse") } "/users" { ok().render("users", mapOf("users" to users.map { it.toDto() })) } } ("/api/users" and accept(APPLICATION_JSON)) { ok().body(users) } ("/api/users" and accept(TEXT_EVENT_STREAM)) { ok().bodyToServerSentEvents(users.repeat().delayElements(ofMillis(100))) } } WebFlux functional API with Kotlin DSL
  • 49. 49 @SpringBootApplication class Application { @Bean fun router(htmlHandler: HtmlHandler, userHandler: UserHandler, articleHandler: ArticleHandler) = router { accept(APPLICATION_JSON).nest { "/api/user".nest { GET("/", userHandler::findAll) GET("/{login}", userHandler::findOne) } "/api/article".nest { GET("/", articleHandler::findAll) GET("/{slug}", articleHandler::findOne) POST("/", articleHandler::save) DELETE("/{slug}", articleHandler::delete) } } (GET("/api/article/notifications") and accept(TEXT_EVENT_STREAM)).invoke(articleHandler::notifications) accept(TEXT_HTML).nest { GET("/", htmlHandler::blog) (GET("/{slug}") and !GET("/favicon.ico")).invoke(htmlHandler::article) } } } Functional router within Boot
  • 50. @Component class HtmlHandler(private val userRepository: UserRepository, private val converter: MarkdownConverter) { fun blog(req: ServerRequest) = ok().render("blog", mapOf( "title" to "Blog", "articles" to articleRepository.findAll() .flatMap { it.toDto(userRepository, converter) } )) } @Component class ArticleHandler(private val articleRepository: ArticleRepository, private val articleEventRepository: ArticleEventRepository) { fun findAll(req: ServerRequest) = ok().body(articleRepository.findAll()) fun notifications(req: ServerRequest) = ok().bodyToServerSentEvents(articleEventRepository.findWithTailableCursorBy()) } 50 Functional handlers within Boot
  • 51. Under construction ... Fixing remaining pain points Coroutines Functional bean definition Multi-platform
  • 52. Immutable non-nullable @ConfigurationProperties @ConfigurationProperties("foo") data class FooProperties( val baseUri: String, val admin: Credential) { data class Credential( val username: String, val password: String) } Boot 2.x ? See issue #8762 for more details @ConfigurationProperties("foo") data class FooProperties( var baseUri: String? = null, var admin = Credentials()) { data class Credential( var username: String? = null, var password: String? = null) } Currently N ot yet available
  • 53. WebTestClient Unusable in Kotlin due to a type inference issue, see KT-5464 otlin 1.3 For now, please use: - WebClient in Kotlin - WebTestClient in Java
  • 54. Under construction ... Fixing remaining pain points Coroutines Boot + functional bean DSL Multi-platform
  • 56. Spring & Kotlin Coroutines 56 ● Coroutines are Kotlin lightweight threads ● Allows non-blocking imperative code ● Less powerful than Reactive API (backpressure, streaming, operators, etc.) ● kotlinx.coroutines: Reactive Streams and Reactor support ● spring-kotlin-coroutine: experimental Spring support (community driven) ● Warning ○ Coroutine are still experimental ○ No official Spring support yet, see SPR-15413 ○ Ongoing evaluation of performances and back-pressure interoperability Experim ental https://github.com/konrad-kaminski/spring-kotlin-coroutine
  • 57. Reactive Coroutines interop 57 Operation Reactive Coroutines Async value fun foo(): Mono<T> suspend fun foo(): T? Async collection fun foo(): Mono<List<T>> suspend fun foo(): List<T> Stream fun foo(): Flux<T> suspend fun foo(): ReceiveChannel<T> Async completion fun foo(): Mono<Void> suspend fun foo()
  • 58. 58 @RestController class CoroutineUserController(val repository: CoroutineUserRepository) { @GetMapping("/user/{id}") suspend fun findOne(@PathVariable id: String): User = repository.findOne(id) @GetMapping("/user") suspend fun findAll(): List<User> = repository.findAll() @PostMapping("/user") suspend fun save(@RequestBody user: User) = repository.save(user) } interface CoroutineUserRepository { suspend fun findOne(id: String): User suspend fun findAll(): List<User> suspend fun save(user: User) } Spring WebFlux with Coroutines Experim ental https://github.com/sdeleuze/spring-kotlin-deepdive/tree/step3-coroutine
  • 59. Under construction ... Fixing remaining pain points Coroutines Boot + functional bean DSL Multi-platform
  • 60. Spring Framework 5 introduces Functional bean definition Very efficient, no reflection, no CGLIB proxy Lambdas instead of annotations Both declarative and programmatic
  • 61. 61 Functional bean definition Kotlin DSL val databaseContext = beans { bean<ArticleEventListener>() bean<ArticleEventRepository>() bean<ArticleRepository>() bean<UserRepository>() environment( { !activeProfiles.contains("cloud") } ) { bean { InitializingBean { initializeDatabase(ref(), ref(), ref()) } } } } fun initializeDatabase(ops: MongoOperations, userRepository: UserRepository, articleRepository: ArticleRepository) { // ... }
  • 62. 62 Beans + router DSL fit well together val context = beans { bean { val userHandler = ref<UserHandler>() router { accept(APPLICATION_JSON).nest { "/api/user".nest { GET("/", userHandler::findAll) GET("/{login}", userHandler::findOne) } } } bean { Mustache.compiler().escapeHTML(false).withLoader(ref()) } bean<HtmlHandler>() bean<ArticleHandler>() bean<UserHandler>() bean<MarkdownConverter>() }
  • 63. 63 Bean DSL is extensible and composable ! webfluxApplication(Server.NETTY) { // or TOMCAT // group routers routes { router { routerApi(ref()) } router(routerStatic()) } router { routerHtml(ref(), ref()) } // group beans beans { bean<UserHandler>() bean<Baz>() // Primary constructor injection } bean<Bar>() mustacheTemplate() profile("foo") { bean<Foo>() } } See https://github.com/tgirard12/spring-webflux-kotlin-dsl POC
  • 64. Functional bean definition with Spring Boot 64 @SpringBootApplication class Application fun main(args: Array<String>) { runApplication<FooApplication>(*args) { addInitializers(databaseContext, webContext) } } This nice syntax currently works only for running the application, not tests
  • 65. Functional bean definition with Spring Boot 65 class ContextInitializer : ApplicationContextInitializer<GenericApplicationContext> { override fun initialize(context: GenericApplicationContext) { databaseContext.initialize(context) webContext.initialize(context) } } context.initializer.classes=io.spring.deepdive.ContextInitializer This more verbose one works for running both application and tests
  • 66. Functional bean definition with Spring Boot 66 Come discussing next steps with us
  • 67. Under construction ... Fixing remaining pain points Coroutines Boot + functional bean DSL Multi-platform
  • 68. Kotlin is multi-platform Kotlin/JVM: JVM and Android Kotlin/JS: transpile to JavaScript Kotlin/Native: run without any VM (LLVM toolchain)
  • 69. 69 Kotlin for frontend today with Kotlin/JS
  • 70. 70 Original JavaScript code if (Notification.permission === "granted") { Notification.requestPermission().then(function(result) { console.log(result); }); } let eventSource = new EventSource("/api/article/notifications"); eventSource.addEventListener("message", function(e) { let article = JSON.parse(e.data); let notification = new Notification(article.title); notification.onclick = function() { window.location.href = "/" + article.slug; }; });
  • 71. 71 Kotlin to Javascript data class Article(val slug: String, val title: String) fun main(args: Array<String>) { if (Notification.permission == NotificationPermission.GRANTED) { Notification.requestPermission().then { console.log(it) } } EventSource("/api/article/notifications").addEventListener("message", { val article = JSON.parse<Article>(it.data()); Notification(article.title).addEventListener("click", { window.location.href = "/${article.slug}" }) }) } fun Event.data() = (this as MessageEvent).data as String // See KT-20743 Type safety, null safety, only 10 Kbytes with Dead Code Elimination tool
  • 72. 72 Kotlin for frontend tomorrow with WebAssembly Read “An Abridged Cartoon Introduction To WebAssembly” by Lin Clark for more details https://goo.gl/I0kQsC A sandboxed native platform for the Web (W3C, no plugin involved)
  • 73. 73 Compiling Kotlin to WebAssembly + ➔ Kotlin supports WebAssembly via Kotlin/Native ➔ Better compilation target than JS: bytecode, performance, memory ➔ DOM API and GC are coming ... ➔ A Kotlin/Native Frontend ecosystem could arise Experim ental
  • 74. Kotlin 1.2 allows sharing code between platforms Multi-platform data types and serialization are coming
  • 75. Thanks! https://speakerdeck.com/sdeleuze/why-spring-loves-kotlin Follow me on @sdeleuze for fresh Spring + Kotlin news https://github.com/mixitconf/mixit https://github.com/sdeleuze/spring-kotlin-fullstack https://github.com/sdeleuze/spring-kotlin-deepdive https://github.com/sdeleuze/spring-kotlin-functional