Spring ❤️ Kotlin #jjug

Preview:

Citation preview

‹#›© 2016 Pivotal Software, Inc. All rights reserved. ‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring ❤ KotlinToshiaki Maki (@making) tmaki@pivotal.io JJUG Night Seminar 2017 Feb 2017-02-20

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Who am I ?• Toshiaki Maki (@making) https://ik.am

•Sr. Solutions Architect @Pivotal

•Spring ☘ / Cloud Foundry ☁ / Concourse ✈ / BOSH 🐚

bit.ly/hajiboot2

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Agenda•Spring Boot with Kotlin •Kotlin support in Spring 5

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Boot with Kotlin

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Initializr

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Initializr

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

package com.example import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication@SpringBootApplication class DemoApplication fun main(args: Array<String>) { SpringApplication.run(DemoApplication::class.java, *args) }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

package com.example import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RestController @RestController class HelloController { @GetMapping("/") fun hello() = "Hello World!" }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

package com.example import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RestController @RestController class HelloController { @GetMapping("/") fun hello() = "Hello World!" }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

// Kotlinopen class AppConfig { @Bean open fun restTemplate() = RestTemplate() }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

// Kotlinopen class AppConfig { @Bean open fun restTemplate() = RestTemplate() }

👇

👇

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

// Kotlinopen class AppConfig { @Bean open fun restTemplate() = RestTemplate() }

👇

👇

😩

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cglib and Spring// Javaclass AppConfig { @Bean RestTemplate restTemplate() { return new RestTemplate(); } }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cglib and Spring// Javaclass AppConfig { @Bean RestTemplate restTemplate() { return new RestTemplate(); } }

Singleton

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cglib and Spring (Pseudo Code)class AppConfig$$ extends AppConfig { @Override RestTemplate restTemplate() { if (context.contains("restTemplate")) { return context.get("restTemplate"); } return super.restTemplate(); } }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cglib and Spring (Pseudo Code)class AppConfig$$ extends AppConfig { @Override RestTemplate restTemplate() { if (context.contains("restTemplate")) { return context.get("restTemplate"); } return super.restTemplate(); } }

Methods in Kotlin are final by default !!

open removes final

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

<plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>${kotlin.version}</version> <configuration> <compilerPlugins> <plugin>spring</plugin> </compilerPlugins> </configuration></plugin>

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

open class AppConfig { @Bean open fun restTemplate() = RestTemplate() }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

open class AppConfig { @Bean open fun restTemplate() = RestTemplate() }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

class AppConfig { @Bean fun restTemplate() = RestTemplate() }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

class AppConfig { @Bean fun restTemplate() = RestTemplate() }

😍

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

http://start.spring.io/#!language=kotlin

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Kotlin support in Spring 5

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Framework 5•Java 8 baseline, Java 9 compatibility •Reactive Support & Spring WebFlux •Router Functions •Performance improvements •HTTP/2 support •Kotlin support

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Kotlin Support

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Kotlin Support

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Kotlin Support•Extension Functions •Reified type parameters

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Kotlin Support•Extension Functions •Reified type parameters

🤔

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

package com.example;

public class Foo { public <T> T create(Class<T> clazz) { try { return clazz.newInstance(); } catch (Exception e) { throw new IllegalStateException(e); } }}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

// JavaFoo foo = new Foo();Bar bar = foo.create(Bar.class);

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

// JavaFoo foo = new Foo();Bar bar = foo.create(Bar.class);

// Kotlinval foo = Foo()val bar = foo.create(Bar::class.java)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

// JavaFoo foo = new Foo();Bar bar = foo.create(Bar.class);

// Kotlinval foo = Foo()val bar = foo.create(Bar::class.java)

👇

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

KClass

Bar::class // kotlin.reflect.KClassBar::class.java // java.lang.Class

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Extension Functions•Extends a class with new functionality without having to inherit from the class •https://kotlinlang.org/docs/reference/extensions.html#extension-functions

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

// Kotlinval foo = Foo()val bar = foo.create(Bar::class.java)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

// Kotlinval foo = Foo()val bar = foo.create(Bar::class.java)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

// Kotlinval foo = Foo()val bar = foo.create(Bar::class)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Extension Functions

// Kotlinval foo = Foo()val bar = foo.create(Bar::class)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Extension Functionspackage com.example

import kotlin.reflect.KClass

fun <T : Any> Foo.create(kclass: KClass<T>) = create(kclass.java)

FooExtensions.kt

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Extension Functionspackage com.example

import kotlin.reflect.KClass

fun <T : Any> Foo.create(kclass: KClass<T>) = create(kclass.java)👇

FooExtensions.kt

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Extension Functions

// Kotlinval foo = Foo()val bar = foo.create(Bar::class)

😍

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reified type parameters •Access a type passed to us as a parameter •https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reified type parameters

inline fun <reified T : Any> Foo.create() = create(T::class.java)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reified type parameters

inline fun <reified T : Any> Foo.create() = create(T::class.java) 👇

👇

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

val foo = Foo()val bar = foo.create(Bar::class)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

val foo = Foo()val bar = foo.create(Bar::class)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reified type parameters

val foo = Foo()val bar = foo.create<Bar>()

😍

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reified type parameters

val foo = Foo()val bar: Bar = foo.create()

😍

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Reified type parameters

val foo = Foo()val bar: Bar = foo.create()

😍

"idiomatic Kotlin code"

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

"idiomatic Kotlin code" with Spring 5

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Application Context

// JavaApplicationContext context = ...;Bar bar = context.getBean(Bar.class);

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Application Context (Extension)

// Kotlinval context = ...val bar = context.getBean(Bar::class)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Application Context (Reified Type)

// Kotlinval context = ...val bar = context.getBean<Bar>()

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Application Context (Reified Type)

// Kotlinval context = ...val bar: Bar = context.getBean()

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

JdbcTemplate

// JavaLong count = jdbcTemplate .queryForObject("SELECT count(*) FROM foo" , Long.class);

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

JdbcTemplate (Extension)

// Kotlinval count = jdbcTemplate .queryForObject("SELECT count(*) FROM foo" , Long::class)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

JdbcTemplate (Reified Type)

// Kotlinval count = jdbcTemplate .queryForObject<Long>( "SELECT count(*) FROM foo")

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

JdbcTemplate (Reified Type)

// Kotlinval count: Long = jdbcTemplate .queryForObject("SELECT count(*) FROM foo")

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RestTemplate

// JavaString foo = restTemplate .getForObject("http://abc.io",String.class);

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RestTemplate (Reified Type)

// Kotlinval foo = restTemplate .getForObject<String>("http://abc.io");

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RestTemplate (Reified Type)

// Kotlinval foo: String = restTemplate .getForObject("http://abc.io");

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RestTemplate

// JavaList<Foo> foos = restTemplate .getForObject("http://abc.io", List<Foo>.class);

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RestTemplate

// JavaList<Foo> foos = restTemplate .getForObject("http://abc.io", List<Foo>.class);

Compile Error!

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RestTemplate

// JavaList<Foo> foos = restTemplate .exchange("http://abc.io", HttpMethod.GET, null, new ParameterizedTypeReference<List<Foo>>() {}).getBody();

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RestTemplate

// JavaList<Foo> foos = restTemplate .exchange("http://abc.io", HttpMethod.GET, null, new ParameterizedTypeReference<List<Foo>>() {}).getBody();

💩

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RestTemplate (Reified Type)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RestTemplate (Reified Type)

// Kotlinval foos: List<Foo> = restTemplate .getForObject("http://abc.io");

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RestTemplate (Reified Type)

// Kotlinval foos: List<Foo> = restTemplate .getForObject("http://abc.io");

😍

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring ❤ Kotlin

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Framework 5•Java 8 baseline, Java 9 compatibility •Reactive Support & Spring WebFlux •Router Functions •Performance improvements •HTTP/2 support •Kotlin support

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Framework 5•Java 8 baseline, Java 9 compatibility •Reactive Support & Spring WebFlux •Router Functions •Performance improvements •HTTP/2 support •Kotlin support

👇👇

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Framework 5•Java 8 baseline, Java 9 compatibility •Reactive Support & Spring WebFlux •Router Functions •Performance improvements •HTTP/2 support •Kotlin support

👇👇 🤔

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

WebMVC + @Controller in Java@RestControllerpublic class UserController { private final UserRepository repo; UserController(UserRepository repo) {/.../} @GetMapping List<User> users() { return repo.findAll(); }}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

WebFlux + @Controller in Java@RestControllerpublic class UserController { private final ReactiveUserRepository repo; UserController(ReactiveUserRepository repo) {/.../} @GetMapping Flux<User> users() { return repo.findAll(); }}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

WebFlux + @Controller in Java@RestControllerpublic class UserController { private final ReactiveUserRepository repo; UserController(ReactiveUserRepository repo) {/.../} @GetMapping Flux<User> users() { return repo.findAll(); }}

Non-Blocking!!

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

WebFlux + RouterFunction in Java

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

WebFlux + RouterFunction in Java

RouterFunction<?> routes = route(GET("/users"), req -> ok() .body(repo.findAll(), User.class));

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

WebFlux + RouterFunction in Kotlin

{ accept(APPLICATION_JSON).apply { GET("/users",{ ok().body(fromPublisher(repo.findAll()) }) }}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Check source code!!

• https://github.com/mix-it/mixit

• https://github.com/making/demo-router-functions

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Other Kotlin Support•Functional Bean Registration with Kotlin •WebFlux functional API, the Kotlin way •Leveraging Kotlin nullable information •Kotlin Script based templates •... •https://speakerdeck.com/sdeleuze/functional-

web-applications-with-kotlin-and-spring-5?

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Release date

https://jira.spring.io/browse/SPR

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

http://start.spring.io/#!language=kotlin

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

http://start.spring.io/#!language=kotlin

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

http://start.spring.io/#!language=kotlin

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

http://start.spring.io/#!language=kotlin

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Resources• https://spring.io/blog/2017/01/04/introducing-kotlin-support-

in-spring-framework-5-0

• https://speakerdeck.com/sdeleuze

• https://blog.ik.am/entries/407

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

CfP for JJUG CCC 2017 Spring •Submit Call for Paper!!! 🙇 •http://www.java-users.jp/?p=2830