作爲一個Scala愛好者,是很想基於 Lightbend 的一套架構進行軟件開發的。Play,Akka,Scala,Spark……。不過理想很豐滿,現實卻很骨感。鑑於那批原教旨主義者,他們對 Spring 已經瘋狂迷戀,我等講道理、講實際的人也只好將 Scala 與 Spring Boot 進行整合。這兩兄弟是和氣的,是友好的,並非有你無他,徹底能夠在能力和現實中實現一個美好的平衡。html
(文章查考了:Scala開發者的SpringBoot快速入門指南 ,謝謝王福強老師的分享。)java
(本文示例在:https://github.com/yangbajing/spring-boot-scala/tree/v01)git
建立支持Scala的Spring Boot應用程序員
Java社區通常使用 Maven或Gradle 管理項目構建,鑑於 Maven 的使用更多,本文將只講解 Maven 下的配置,Gradle 的配置請讀者自行參考網上實現。固然,做爲一個 Scalar ,基於 Sbt 的配置是確定會講到的,在 Sbt 下還有一個神器:sbt-package-native ,敬待下文詳解。github
首先來看看配置文件 pom.xmlweb
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>me.yangbajing.springscala</groupId> <artifactId>springscala</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springscala</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> <scala.version>2.11.7</scala.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${scala.version}</version> </dependency> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-compiler</artifactId> <version>${scala.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.2.2</version> <executions> <execution> <id>compile-scala</id> <phase>compile</phase> <goals> <goal>add-source</goal> <goal>compile</goal> </goals> </execution> <execution> <id>test-compile-scala</id> <phase>test-compile</phase> <goals> <goal>add-source</goal> <goal>testCompile</goal> </goals> </execution> </executions> <configuration> <recompileMode>incremental</recompileMode> <compileOrder>Mixed</compileOrder> <scalaVersion>${scala.version}</scalaVersion> <args> <arg>-deprecation</arg> </args> <jvmArgs> <jvmArg>-Xms64m</jvmArg> <jvmArg>-Xmx1024m</jvmArg> </jvmArgs> </configuration> </plugin> </plugins> </build> </project>
對於 Spring 部分的配置,這裏就很少說了。重點說下 Scala 方面的配置。spring
首先你須要加入 Scala 的依賴庫,這裏加入了 scala-library
和 scala-compiler
兩個包的依賴,這是在Java環境下編譯 Scala 代碼所必需的。shell
其次就是要添加 scala-maven-plugin
插件,以讓 Maven 支持對 Scala 的編譯操做。這裏須要注意的是 recompileMode
指令,推薦使用 incremental 配置。apache
另外一個須要注意的配置薦就是 compileOrder
,當項目同時使用了Java和Scala兩種語言時它決定了二者的編譯順序。默認是 Mixed (混合順序),其它還有兩個選項是:JavaThenScala 和 ScalaThanJava。api
如今咱們可使用 Scala 來編寫 spring boot 應用了,先來寫一個 POJO 類。
class Message { @BeanProperty var value: String = _ }
再來寫一個 Controller :
@RestController @RequestMapping(Array("/api")) class ApiController { @RequestMapping(value = Array("/hello"), method = Array(RequestMethod.GET)) @ResponseBody def hello(): Message = { TimeUnit.SECONDS.sleep(6) val message = new Message() message.value = "Hello, Scala for Spring!" message } }
這裏須要注意的是註解參數的傳遞方式,Scala 裏沒像 Java 同樣會自動把字符串轉換成註解裏定義的數組參數,咱們須要顯示的定義一個數據傳入。並且傳入註解的參數值只能是一個常量,好比:"/api/user"
,不能像這樣:Constant.API_PATH + "/user"
。
打開終端,執行如下指令啓動 spring boot 應用:
mvn spring-boot:run
再打開一個終端,測試 API 功能:
time curl -v http://localhost:8080/hello
這裏使用了 .scala
的方式來配置 sbt 項目。sbt 的配置文件在項目根目錄下的 project
目錄:
project/ ├── Build.scala ├── build.properties
在 build.properties
文件內指定了 sbt 的版本號,Build.scala
文件設置了詳細的 Sbt 工程設置及編譯選項等。咱們先來看看配置文件內容:
import sbt.Keys._ import sbt._ object Build extends Build { override lazy val settings = super.settings :+ { shellPrompt := (s => Project.extract(s).currentProject.id + " > ") } lazy val root = Project("springscala", file(".")) .settings( description := "Spring boot scala", version := "0.0.1", homepage := Some(new URL("https://github.com/yangbajing/spring-boot-scala")), organization := "me.yangbajing", organizationHomepage := Some(new URL("http://www.yangbajing.me")), startYear := Some(2016), scalaVersion := "2.11.7", scalacOptions ++= Seq( "-encoding", "utf8", "-unchecked", "-feature", "-deprecation" ), javacOptions ++= Seq( "-source", "1.8", "-target", "1.8", "-encoding", "utf8", "-Xlint:unchecked", "-Xlint:deprecation" ), offline := true, libraryDependencies ++= Seq( _springBootStarterWeb, _springBootStarterTest)) val verSpringBoot = "1.3.3.RELEASE" val _springBootStarterWeb = "org.springframework.boot" % "spring-boot-starter-web" % verSpringBoot val _springBootStarterTest = "org.springframework.boot" % "spring-boot-starter-test" % verSpringBoot }
沒錯,sbt 的配置文件就是實打實的 Scala 代碼。sbt 也有一套像 Gradle 同樣的 DSL 來定義項目配置信息,是之後綴 .sbt
結尾的文件。不過我的仍是認爲直接使用 Scala 代碼作配置更直觀、清晰。
具體配置含義,我這裏就不細講了。官方有很詳細的教程和文檔說明:sbt Reference Manual 。
Scala 從各方面來看,配置和代碼,期簡潔性都是優於Java。對於一個Scala愛好者,你的選擇不少,好比:Play。不過,不少時候你須要考慮到各方面的利益。公司、團隊、意願等各方面。現實中,Spring 在 Java 生態圈仍是使用最多的技術,Spring 框架的使用自己是未限制 JVM 平臺上的各類主義的,它也能夠很好的支持:Groovy、Kotlin 甚至 Clojure……
本文簡單講解了怎樣配置 pom.xml 以在 Spring boot 中支持 Scala,以及 sbt 工程又是怎樣支持 Spring 的。這便是 Scala 開發者的 Spring boot 入門指南,亦但是 Java 程序員的 Scala 第一次嘗試。但願能打開一座橋樑,讓 Java 程序員開眼界,Scala 開發者務實。
下一篇文章我想進一步介紹下使用 Scala 開發 Spring 應用的一些好處和慣用法,接下來的文章還會講到怎樣結合 Akka 基於 Spring 開發一個 WebSocket 應用。
本系列文章