介紹 Spring Scala

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

去年十月,在 SpringOne2GX 大會上,我向世界介紹了 Spring Scala 專案。從那時起,我也在 Devoxx 大會上展示了這個專案。在這篇部落格文章中,我想要更詳細地介紹這個專案,以及如何在您的 Scala 專案中使用它。

為何選擇 Spring Scala?

Spring Scala 專案的目標很簡單,就是讓在 Scala 中使用 Spring 框架更加容易。我們相信有很多 Spring 使用者想要嘗試 Scala,但不希望捨棄他們使用 Spring 的經驗。這個專案就是為這些人而設計的。

顯然地,即使沒有 Spring Scala,您今天仍然可以在 Scala 中使用 (Java) Spring Framework。但這樣做在某些地方會顯得笨拙。就像任何程式語言一樣,Scala 有自己獨特的方式來做事,而在 Scala 中使用像 Spring 這樣純粹的 Java 框架會感覺「太 Java 風格」。Spring Scala 試圖透過使 Spring 成為 Scala 語言的一等公民來解決這個問題。

Spring Scala 概觀

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

在 XML 中配置 beans

在 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 Collections 的章節。

在 Scala 中配置 beans

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

若要建立函數式 Spring 設定,您只需將 FunctionalConfiguration trait 混入您的設定類別中。Bean 是透過在 trait 上呼叫 bean 方法並傳入一個建立 bean 的函數來定義的。

假設有上面顯示的 Person 類別,我們可以像這樣在函數式設定中配置它


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

當然,您也可以使用特定名稱註冊 bean、提供別名或設定 scope


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 Templates

Spring 的 templates 是很有用的工具類別,有助於任何形式的資料存取或資源處理。Spring Scala 包含 wrappers,可以調整 (Java) templates 以更符合 Scala 的使用習慣。一般來說,這些 Scala template wrappers 在 Scala 語言中使用時,相較於 Java 版本有三個改進

  • 使用函數而不是回呼介面
  • 在 Java 版本可能傳回 null 的地方使用 Option
  • 使用 class manifests 而不是 class parameters

透過這三個改進,您可以像這樣使用 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")
}

一般來說,template wrappers 的 Scala 版本與它們的 Java 對應版本位於相同的套件中,只是中間有一個 scala 套件。因此,例如 JmsTemplate 的 Scala 版本位於 org.springframework.scala.jms.core 中。在撰寫這篇文章時,存在以下 Scala 友善的 templates

  • SimpleJdbcTemplate
  • JmsTemplate
  • RestTemplate
  • TransactionTemplate

有關在 Scala 中使用 Spring Templates 的更多資訊,請參閱 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 issue 來提出功能請求,或是在 GitHub 上留下 pull request。

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

取得 Spring 電子報

隨時接收 Spring 電子報的最新消息

訂閱

領先一步

VMware 提供訓練和認證,以加速您的進展。

了解更多

取得支援

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

了解更多

即將到來的活動

查看 Spring 社群中所有即將到來的活動。

查看全部