Kotlin Spring 5: Dependency Injection Part 1
Technologies used: Kotlin 1.2.10 | Spring 5 | Maven 3.3.9 | Spring-boot 2.0.0.M7
In this first post, we will look into the simple Dependency Injection with Spring. There is nothing new, some tips to make it smooth.
For the easy of this example, I have created a Spring Service with an Interface GreetingService and a class GreetingServiceImpl
package vn.finixasia.didemo.services interface GreetingService { fun sayGreeting(): String }
package vn.finixasia.didemo.services import org.springframework.stereotype.Service @Service class GreetingServiceImpl : GreetingService { private val HELLO_GURUS = "Hello !!!" override fun sayGreeting(): String { return HELLO_GURUS } }
Boot Application
To work, Spring need a context, for the example, we will use a SpringBootApplication
package vn.finixasia.didemo import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication import vn.finixasia.didemo.controllers.ConstructorInjectedController import vn.finixasia.didemo.controllers.MyController import vn.finixasia.didemo.controllers.PropertyInjectedController @SpringBootApplication class DiDemoApplication fun main(args: Array<String>) { var ctx = SpringApplication.run(DiDemoApplication::class.java, *args) var controller = ctx.getBean("myController") as MyController controller.hello() println(ctx.getBean(PropertyInjectedController::class.java).sayHello()) println(ctx.getBean(ConstructorInjectedController::class.java).sayHello()) }
Injection by Properties
Injection by Property is possible with Kotlin, but not recommended. I just show here how to make it work as it is a little bit tricky.
package vn.finixasia.didemo.controllers import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Controller import vn.finixasia.didemo.services.GreetingService @Controller class PropertyInjectedController { @Autowired lateinit var greetingService: GreetingService fun sayHello(): String? { return greetingService.sayGreeting() } }
As greetingService is a non-null value, we should initialize his value at the constructor, and this is non-convenient, so we use the key lateinit, to notice Kotlin, the property will be non-null, but it will be set later, not at the constructor.
Injected by Constructor
package vn.finixasia.didemo.controllers import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Controller import vn.finixasia.didemo.services.GreetingService @Controller class ConstructorInjectedController @Autowired constructor(val greetingService: GreetingService) { fun sayHello(): String? { return greetingService.sayGreeting() } }
The @Autowired annotation is not anymore mandatory since Spring 4.3, I like to keep it has it is self-explanatory.