Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Playing With Spring Boot, Vaadin, and Kotlin

DZone's Guide to

Playing With Spring Boot, Vaadin, and Kotlin

Spring Boot and Vaadin enthusiast, Nicolas Frankel, takes us through building an application in the JVM language Kotlin, using the two frameworks.

· Java Zone
Free Resource

Bitbucket is for the code that takes us to Mars, decodes the human genome, or drives your next car. What will your code do? Get started with Bitbucket today, it's free.

It’s no mystery that I’m a fan of both Spring Boot and Vaadin. When the Spring Boot Vaadin add-on became GA, I was ecstatic. Lately, I became interested in Kotlin, a JVM-based language offered by JetBrains. Thus, I wanted to check how I could develop a small Spring Boot Vaadin demo app in Kotlin – and learn something in the process. Here are my discoveries, in no particular order.

Spring Needs Non-final Stuff

It seems Spring needs @Configuration classes and @Bean methods to be non-final. As my previous Spring projects were in Java, I never became aware of that because I never use the final keyword. However, Kotlin classes and methods are final by default: hence, you have to use the open keyword in Kotlin.

@Configuration
open class AppConfiguration {
    @Bean
    @UIScope
    open fun mainScreen() = MainScreen()
}

No Main Class

Spring Boot applications require a class with a public static void main(String... args) method to reference a class annotated with @SpringBootApplication. In general, those two classes are the same.

Kotlin has no concept of such static methods, but offers pure functions and objects. I tried to be creative by having an annotated object referenced by a pure function, both in the same file.

@SpringBootApplication
open class BootVaadinKotlinDemoApplication

fun main(vararg args: String) {
    SpringApplication.run(arrayOf(BootVaadinKotlinDemoApplication::class.java), args)
}

Different Entry-point Reference

Since the main function is not attached to a class, there’s no main class to reference to launch inside the IDE. Yet, Kotlin creates a .class with the same name as the file name suffixed with Kt.

My file is named BootVaadinKotlinDemoApplication.kt, hence the generated class name is BootVaadinKotlinDemoApplicationKt.class. This is the class to reference to launch the application in the IDE. Note that there’s no need to bother about that when using mvn spring-boot:run on the command-line, as Spring Boot seems to scan for the main method.

Short and Readable Bean Definition

Java syntax is seen as verbose. I don’t think it’s a big issue when its redundancy is very low compared to the amount of useful code. However, in some cases, even I have to admit it’s a lot of ceremony for not much. When of such case is defining beans with the Java syntax:

@Bean @UIScope
public MainScreen mainScreen() {
    return new MainScreen();
}

Kotlin cuts through all of the ceremony to keep only the meat:

  • No semicolon required
  • No new keyword
  • Block replaced with an equal sign since the body consists of a single expression
  • No return keyword required as there’s no block
  • No return type required as it can easily be inferred
@Bean @UIScope
fun mainScreen() = MainScreen()

Spring configuration files are generally quite long and hard to read. Kotlin makes them much shorter, without sacrificing readability.

The init Block is Your Friend

In Java, the constructor is used for different operations:

  1. storing arguments into attributes
  2. passing arguments to the super constructor
  3. other initialization code

The first operation is a no-brainer because attributes are part of the class signature in Kotlin. Likewise, calling the super constructor is handled by the class signature. The rest of the initialization code is not part of the class signature and should be part of an init block. Most applications do not this part, but Vaadin needs to setup layout and related stuff.

class MainScreenPresenter(tablePresenter: TablePresenter,
                          buttonPresenter: NotificationButtonPresenter,
                          view: MainScreen, eventBus: EventBus) : Presenter<MainScreen>(view, eventBus) {

    init {
        view.setComponents(tablePresenter.view, buttonPresenter.view)
    }
}

Use the Apply Method

Kotlin has a standard library offering small dedicated functions. One of them is apply, defined as inline fun T.apply(f: T.() -> Unit): T (source). It’s an extension function, meaning every type will have it as soon as it’s imported into scope. This function requires an argument that is a function and that returns nothing. Inside this function, the object that has been apply-ed is accessible as this (and this is implicit, as in standard Java code). It allows code like this:

VerticalLayout(button, table).apply {
    setSpacing(true)
    setMargin(true)
    setSizeFull()
}

Factor View and Presenter into Same File

Kotlin makes code extremely small, thus some files might be only a line long (not counting import). Opening different files to check related classes is useless. Packages are a way to organize your code; I think files might be another way in Kotlin. For example, Vaadin views and presenters can be put into the same file.

class NotificationButton: Button("Click me")

class NotificationButtonPresenter(view: NotificationButton, eventBus: EventBus): Presenter<NotificationButton>(view, eventBus) { ... }

Lambdas Make Great Listeners

As of Java 8, single-method interfaces implemented as anonymous inner classes can be replaced with lambdas. Kotlin offers the same feature plus:

  • It allows to omit parentheses if the lambda is the only argument
  • If the lambda has a single argument, its default name is it and it doesn’t need to be declared

Both make for a very readable syntax when used in conjunction with the Vaadin API:

view.addValueChangeListener {
    val rowId = it.property.value
    val rowItem = view.containerDataSource.getItem(rowId)
    eventBus.publish(SESSION, rowItem)
}

Note: still, more complex logic should be put into its own function.

Bitbucket is the Git solution for professional teams who code with a purpose, not just as a hobby. Get started today, it's free.

Topics:
kotlin ,spring boot ,vaadin

Published at DZone with permission of Nicolas Frankel, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}