uncategorized

Setting up command line Spring Boot 2 with Kotlin

In this article we’ll take a look how to set up Spring configuration into a Kotlin project. We will add needed Spring dependencies and create an application to run a simple Hello World web service. I will be using a base project from an earlier post to build on top of. You can find the source code for that from Github.

If you are not familiar with it: Spring is a framework that most if not all Java developers are familiar with, it is the most used framework in enterprise environments. Note that even though the word enterprise might raise some ill thoughts in you, there is still a place for a little bit of Spring in this world.

The behemoth known as Spring Framework has slimmed down a lot over the last few years and has finally caught up with other microframeworks like Vert.x, Dropwizard or Ratpack and has also at the same time kept its advantage over other web application frameworks like Play. Nowadays Spring comes knocking at your door Boot first and pushing users out of the configuration/XML hell it was known for. Spring Boot is combining best of both worlds, the vastness, stability and familiarity of Spring Framework and everything around it, plus the easeness of auto configuration, micro framework settings and fat jar deployments.

Spring 5 is the newest version of the framework and big changes on that are new Reactive APIs as well as first class support of Kotlin. The latter one interests us a lot at this point, though we will also touch the former a little bit later on in the series. Spring developers have truly embraced Kotlin and they like the language a lot. They have built new functional routing capabilities and Kotlin DSL within their framework for all Kotlinites to have fun with. Naturally this all works so well because Kotlin is brilliant with its interoperability with Java. In your project you can mix and match both languages as you like, in our case we will leave the grandfather behind telling stories about his glory days and jump into full Kotlin codebase.

Spring has matured to version 5 this year and subsequently Spring Boot will be reaching version number 2. At the time of this post the framework is in Release Candidate state and Spring Boot is churning out milestone releases so we will go with those instead of final release versions. To include these dependencies into our application we need to add a new dependency to our Gradle build. Spring has also developed a plugin for Spring Boot dependencies and that will be our helper throughout this application development and guide us towards correct modules.

To add Spring dependencies to the application we use Gradle and dump in few dependencies to help us. We’ll add in Spring-Boot-Starter-Web and Spring-Boot-Devtools. Devtools is especially useful when running the application though the IDE, giving us the ability to hot swap our application classes without the need to restart the application server.

1
2
compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
compile("org.springframework.boot:spring-boot-devtools:$springBootVersion")

We will also include Spring dev tools for some developer ergonomics. With these dev tools we gain the ability to hot swap our application classes when we have done some changes to them, gaining us the possibility to increase our development velocity quite a bit. When codebases get large enough, restart times tend to increase as well. If we would have to restart the application after every change and wait that 30 seconds per operation it would eat a lot of development time during the day. Granted, Spring Dev tools isn’t extremely magical and might sometimes fail but regardless that and the JVMs ability to hot swap lines of code gives us a very very good start.

When we have our Spring Boot 2 web dependencies in our Gradle build we can start creating our first web app. First thing we can touch is a simple REST controller that return a string to the browser when the endpoint is hit. Second thing is to return some HTML and views. Spring has a built-in view resolver system that serves static templates for us. In our case though we will be using programmatic views that are built with Kotlin HTML DSL. We’ll touch that a little bit more in the next blog post.

The controller we create uses Spring annotation @RestController and it has a single fun with @GetMapping annotation:

1
2
3
4
5
6
@RestController
class IndexController{
@GetMapping
fun index() = "Hello"
}

That is everything we need to run a Spring Boot web application and serve JSON to the browser. In reality this controller would be having injected dependencies and our index function would pass on execution to those dependencies for more complex business logic. Let’s create a simple Spring service to respond with that “Hello” string instead of hardcoding it in.

1
2
3
4
5
6
7
interface Simple {
fun respond(): String
}
class SimpleImple: Simple {
override fun respond() = "Hello"
}

And to inject this to our controller we can simply add it to be a constructor argument in our controller.

1
2
3
@RestController
class IndexController(private val simple: Simple) {
/** snip **/

We are creating and injecting the interface just in case if we want to swap the implementation to another one at some point. Spring has a useful ability to use different profiles and return different implementations based on a chosen profile. This comes handy in cases where we are discussing with application boundaries like database and external services and we don’t want to hit the production DB/service during development, testing or simply want to point to a different place at different times.

Before getting this application to run on its own we need to create Spring context and spin that up with all the needed dependencies. For that we can create a new Kotlin file with our main class and our main function. Within our main function we can also define our functional Spring beans to be loaded and injected to the context.

1
2
3
4
5
6
7
8
9
10
11
12
@SpringBootApplication
class Config
fun main(args: Array<String>){
val application = SpringApplication(Config::class.java)
application.addInitializers(ApplicationContextInitializer<GenericApplicationContext> { ctx ->
beans{
bean<Simple>()
}.initialize(ctx)
})
application.run(*args)
}

If using IntelliJ the startup of this application is simple. If we navigate to our config file and click on the gutter of our main function we can spin up our Spring Boot app and start serving simple strings to the browser for all users that are interested in reading them.

Share