Spring Scala 簡介

工程 | Arjen Poutsma | 2012 年 12 月 10 日 | ...

去年十月,我在 SpringOne2GX 大會上向全世界介紹了 Spring Scala 專案。自那以後,我還在 Devoxx 大會上展示了這個專案。在這篇部落格文章中,我將進一步詳細介紹這個專案以及如何在您的 Scala 專案中使用它。

為何選擇 Spring Scala?

Spring Scala 專案的目標很簡單:讓在 Scala 中使用 Spring 框架變得更容易。我們相信有很多 Spring 使用者想要嘗試 Scala,但又不想放棄他們使用 Spring 的經驗。這個專案正是為這些人準備的。

顯然,今天您可以在 Scala 中使用(Java)Spring 框架,無需 Spring Scala。但在某些地方這樣做會很彆扭。就像任何程式語言一樣,Scala 有自己獨特的方式做事,在 Scala 中使用一個純 Java 框架如 Spring 會感覺“太 Java 味兒”了。Spring Scala 試圖透過讓 Spring 成為 Scala 語言的一等公民來解決這個問題。

Spring Scala 概覽

Spring Scala 正在進行中。在這篇文章的其餘部分,我將重點介紹目前已經實現的功能。然而,我們預計在接下來的幾個月會新增許多額外功能,希望是透過您提供的反饋來實現。因此,如果您對某個功能有想法,認為它能讓在 Scala 中使用 Spring 更愉快,請透過提交 JIRA 問題 或留言來告訴我們。

在 XML 中裝配 Bean

在 Spring XML 應用上下文中裝配 Scala Bean 最簡單且首選的方式是使用建構函式注入。例如,假設我們有以下 Scala 類:


class Person(val firstName: String, val lastName: String)

您可以使用 c 名稱空間如下裝配這個類:


<bean id="person" class="Person" c:firstName="John" c:lastName="Doe"/>

請注意,透過將建構函式注入與 val 結合使用,我們還使得 Person 類不可變。函式式語言(如 Scala)鼓勵使用不可變資料結構。因此,在 Scala 中使用 Spring 時首選建構函式注入。另外請注意,建構函式注入是開箱即用的;它無需在類路徑中包含 Spring Scala jar 包即可工作。

說到 setter 注入,事情就變得有點複雜了。預設情況下,Scala 類不遵循 JavaBeans 屬性契約(例如 String getFoo()void setFoo(String))。相反,Scala 有自己的屬性契約:“getter”不以 get 為字首,而是使用欄位名作為方法名(例如 foo: String)。Scala 的 setter 則在欄位名後加上 =(例如 foo=(String): Unit)。

為了解決這個問題,您可以指示 Scala 編譯器使用 @scala.reflect.BeanProperty 註解生成 JavaBeans getter 和 setter;或者您可以在類路徑中新增 Spring Scala 以啟用對 Scala setter 的支援。

使用 @BeanProperty 就像用它註解一個 var 一樣簡單:


class Person(@BeanProperty var firstName: String, @BeanProperty var lastName: String)

這將導致為該類建立 JavaBean 風格的 setter,以便您可以非常簡單地在 XML 中裝配它:


<bean id="constructor" class="Person" p:firstName="John" p:lastName="Doe"/>

作為使用此註解的替代方案,從版本 3.2 開始,Spring 支援使用 BeanInfoFactory 策略介面來支援任意的 getter 和 setter。Spring Scala 專案包含此介面的一個實現,該實現支援 Scala 的 getter 和 setter。Spring 會自動檢測到此實現,無需額外的配置。

實際上,這意味著將 Spring Scala jar 包放在類路徑中將啟用對 Scala 屬性的支援,並且您可以使用上面的 XML 配置來裝配 Person 類,而無需新增 @BeanProperty 註解。

有關在 Spring XML 中裝配 Scala Bean 的更多資訊,請參閱 Spring Scala 文件 Wiki 的相關章節。另請參閱有關在 Spring XML 中裝配 Scala 集合的章節。

在 Scala 中裝配 Bean

除了在 XML 中定義 Bean,Spring Scala 還提供了一種替代方案,它使用 Scala 類而不是 XML 檔案來配置您的 Spring Bean。這種方法類似於在 Spring Java 中使用 @Configuration,不同之處在於它是基於函式而不是註解。

要建立一個函式式 Spring 配置,您只需在配置類中混入 FunctionalConfiguration 特質即可。Bean 透過呼叫該特質上的 bean 方法並傳入一個建立 Bean 的函式來定義。

給定上面展示的 Person 類,我們可以在函式式配置中如下裝配它:


class PersonConfiguration extends FunctionalConfiguration {
    bean() {
        new Person("John", "Doe")
    }
}

當然,您也可以將 Bean 註冊到特定的名稱下,提供別名,或設定作用域:


class PersonConfiguration extends FunctionalConfiguration {
    bean("john", aliases = Seq("doe"), scope = BeanDefinition.SCOPE_PROTOTYPE) {
        new Person("John", "Doe")
    }
}

然後,您可以使用此配置類建立 Spring 應用上下文:


object PersonConfigurationDriver extends App {
    val applicationContext = new FunctionalConfigApplicationContext(classOf[PersonConfiguration])
    val john = applicationContext.getBean(classOf[Person])
    println(john.firstName)
}

有關函式式 Bean 配置的更多資訊,包括強型別 Bean 引用、如何匯入 XML 檔案和 @Configuration 類以及如何在 profile 中包裝 Bean 定義的章節,請參閱 Spring Scala 文件 Wiki 的相關章節

在 Scala 中使用 Spring 模板

Spring 的模板是實用的工具類,有助於一般的資料訪問或資源處理。Spring Scala 包含一些包裝器,可將(Java)模板適配得更適合 Scala 使用。總的來說,這些 Scala 模板包裝器在使用時相比 Java 版本有三個改進:

  • 使用函式代替回撥介面
  • 在 Java 版本可能返回 null 的地方使用 Option
  • 使用類 manifest 代替類引數

透過這三個改進,您可以如下使用 JmsTemplate


val connectionFactory : ConnectionFactory = ...
val template = new JmsTemplate(connectionFactory)

template.send("queue") {
    session: Session => session.createTextMessage("Hello World")
}

template.receive("queue") match {
    case Some(textMessage: TextMessage) => println(textMessage.getText)
    case _ => println("No text message received")
}

通常,模板包裝器的 Scala 版本與其 Java 對應版本位於相同的包中,只是中間多了一個 scala 包。例如,JmsTemplate 的 Scala 版本位於 org.springframework.scala.jms.core。截至撰寫本文時,存在以下適合 Scala 的模板:

  • SimpleJdbcTemplate
  • JmsTemplate
  • RestTemplate
  • TransactionTemplate

有關在 Scala 中使用 Spring 模板的更多資訊,請參閱 Spring Scala 文件 Wiki 的相關章節

可用性

Spring Scala 的第一個里程碑版本可在我們的里程碑倉庫 http://repo.springsource.org/libs-milestone 下載。對於 Maven 使用者:

<repositories>
    <repository>
        <id>milestone.repo.springsource.org</id>
        <name>repo.springsource.org-milestone</name>
        <url>https://repo.springsource.org/libs-milestone</url>
    </repository>
</repositories>
<dependency>
    <groupId>org.springframework.scala</groupId>
    <artifactId>spring-scala</artifactId>
    <version>1.0.0.M2</version>
</dependency>

專案本身可在 GitHub 獲取。如果您想貢獻,可以透過為功能請求提交 JIRA 或在 GitHub 提交 pull request 來進行。

注意:截至 2013-04-02,已經發布了一個新的里程碑版本。請閱讀論壇公告

訂閱 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

先行一步

VMware 提供培訓和認證,助您快速發展。

瞭解更多

獲取支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案。

瞭解更多

即將舉辦的活動

檢視 Spring 社群所有即將舉辦的活動。

檢視全部