介紹 Spring Scala

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

去年十月,在 SpringOne2GX 大會上,我向全世界介紹了 Spring Scala 專案。此後,我還在 Devoxx 上介紹了這個專案。在這篇博文中,我想進一步詳細介紹這個專案以及如何在您的 Scala 專案中使用它。

為什麼選擇 Spring Scala?

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

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

Spring Scala 概述

Spring Scala 仍在開發中。在這篇文章的其餘部分,我將重點介紹當前已實現的功能。但是,我們預計在未來幾個月內會增加許多額外功能,希望透過您提供的反饋來實現。因此,如果您對某個功能有想法,能讓 Spring 在 Scala 中使用起來更愉快,請透過提交 JIRA issue 或留言告訴我們。

在 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 文件維基的相關部分。另請參閱有關在 Spring XML 中裝配 Scala 集合的部分。

在 Scala 中裝配 Bean

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

要建立函式式 Spring 配置,您只需將 FunctionalConfiguration trait 混入您的配置類中。透過呼叫 trait 上的 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 類以及如何將 bean 定義包裝在配置檔案中的部分,請參閱 Spring Scala 文件維基的相關部分

在 Scala 中使用 Spring 模板

Spring 的模板是有用的工具類,它們有助於各種資料訪問或資源處理。Spring Scala 包含介面卡,它們將 (Java) 模板調整為更適合 Scala。通常,這些 Scala 模板介面卡在 Scala 語言中的使用方面比 Java 版本有三個改進

  • 使用函式而不是回撥介面
  • 在 Java 版本可能返回 null 的地方使用 Option
  • 使用類清單而不是類引數

透過這三個改進,您可以例如如下使用 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 文件維基的相關部分

可用性

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 上留下拉取請求。

請注意,截至 2013-04-02,已釋出新的里程碑版本。請閱讀論壇公告

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

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

檢視所有