Using Spring Boot on Scala
Assumption
This example uses a project generated/seeded via Activator using the “minimal-scala” template. However, any project using SBT will probably work just as well.
Add Spring Boot to dependencies
Add Spring Boot dependencies to build.sbt:
libraryDependencies += "org.springframework.boot" % "spring-boot-starter" % "1.3.2.RELEASE" libraryDependencies += "org.springframework.boot" % "spring-boot-starter-test" % "1.3.2.RELEASE"
Create a SpringBootApplication and run it
package com.example @SpringBootApplication class HelloApp { } object Hello { def main(args: Array[String]): Unit = { SpringApplication run classOf[HelloApp] } }
This class serves as a package “anchor” for component scanning. The singleton exports an equivalence of a “public static void main(String args[])” entry point.
At this point, “sbt run” will bring up the app, but it will quit soon afterward.
Time to decide if this will be a Web app or a Command line app.
Branch to Web or Command line (console)
Web app
To create a Web app, add the spring-boot-starter-web dependency. Add this to build.sbt:
libraryDependencies += "org.springframework.boot" % "spring-boot-starter-web" % "1.3.2.RELEASE"
That’s it! Now running “sbt run” will bring up the Web app listening on port 8080.
Command line app
To create a command line app (or to add a command line runner to a Web app such as above), modify the main app class:
@SpringBootApplication class HelloApp extends CommandLineRunner { override def run(args: String*): Unit = { println("Hello from Command line runner!") } }
Extending CommandLineRunner in Scala is the same as implementing CommandLineRunner in Java. So just implement the run method.
Try Autowiring something
Assuming the app class is com.example.HelloApp. The component scanning starts at com.example. So create a service class under that package (or a subpackage thereof). I will create one under com.example.services:
package com.example.services import org.springframework.stereotype.Service @Service class HelloService { def hello(): String = { "Hello from HelloService!" } }
Autowire into a bean using the service (HelloApp in this example):
@SpringBootApplication class HelloApp extends CommandLineRunner { @Autowired var helloSvc: HelloService = null override def run(args: String*): Unit = { println(helloSvc.hello()) } }
Configuration properties
Configuration properties can go into src/main/resources/application.properties, same as in Java world:
titlemsg=Hello App
Accessing properties is also pretty much the same (e.g. shown here using @Value):
@SpringBootApplication class HelloApp extends CommandLineRunner { ... @Value("${titlemsg}") var titleMsg: String = null override def run(args: String*): Unit = { println(titleMsg) } }
There are several implementations of the @Value annotation available, be sure to use the one from Spring:
org.springframework.beans.factory.annotation.Value
Logging
And logging. Adding src/main/resources/logback.xml will allow tweaking of logging behavior:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/base.xml"/> <logger name="com.example" level="DEBUG"/> </configuration>
I use Log4j, so here’s how to add a logger into the class to log with:
class HelloApp extends CommandLineRunner { val logger = Logger getLogger classOf[HelloApp] override def run(args: String*): Unit = { logger info "Hello using logger" } }