Spring Data Codd RC1 有哪些新特性?

工程 | Oliver Drotbohm | 2014 年 2 月 7 日 | ...

隨著我們開發的 Spring Data 釋出列車臨近終點,我想是時候簡要概述一下本次釋出將引入的一些新特性了。

如果您還不知道,釋出列車是多個 Spring Data 模組的協調發布,旨在確保它們開箱即用無縫協作。當前的釋出列車以關係模型的發明者 Edgar F. Codd 命名。

Spring Data Commons

作為釋出列車中所有其他模組的基礎,Spring Data Commons 模組中的新特性也可用於各個儲存模組。

對於 Codd 版本,我們將所需的最低 Spring 版本提高到 3.2.7,並改進了與 Spring 4.0 的相容性,以便在更新到迄今為止最新最好的 Spring 版本時提供無縫體驗。當您使用 Spring 4 和 Java 8 執行應用程式時,Spring Data 審計功能現在能夠使用 JSR-310 型別填充實體的建立和修改日期。

abstract class BaseEntity {
    
    @CreatedDate ZonedDateTime createdDate;
    @LastModifiedDate ZonedDateTime modifiedDate;
}

此外,現在通常可以使用模組特定的 @Enable…Auditing 註解啟用審計功能(更多內容請參閱 Thomas Darimont 關於第一個里程碑中引入的新特性的部落格文章)。

從 Codd 開始,Spring Data repository 將被立即例項化,以確保 repository 介面的驗證被立即觸發,即使在容器啟動時沒有顯式請求 repository 例項的注入點。要回退到舊行為,請在 repository 介面上使用 @Lazy 註解,就像您習慣於使用其他 Spring bean 定義一樣。

在 Spring MVC 的 Web 支援領域,Spring Data 的 PagedResourcesAssembler 現在會建立符合 RFC-6570 標準的頁面導航連結。因此,假設您有一個像這樣的 Spring MVC 控制器

@Controller
class OrderController {
    
    @RequestMapping("/orders")
    HttpEntity<PagedResources<Resource<Order>>> showOrders(Pageable pageable, 
        PagedResourcesAssembler<Order> assembler) {

        Page<Order> orders = orderRepository.findAll(pageable);
        return new ResponseEntity<>(assembler.toResource(orders), HttpStatus.OK);
    }
}

PagedResourcesAssembler 將檢查給定的 Page 型別的 Order 集合,渲染內容、頁面元資訊,並酌情新增 prevnext 連結。

GET /orders?page=0&size=10
Accept: application/hal+json

200 OK
{ _links : { self : { href : "/orders{?page,size,sort}",
                      templated : true },
             next : { href : "/orders?page=1&size=10" }},

  _embedded :  { orders : [ … ] },

  page : {
    size : 1,
    totalElements : 2,
    totalPages : 2,
    number : 0
  }
}

如您所見,self 連結清楚地表明瞭資源接受哪些引數來自定義響應。next 連結提供了訪問與當前給定引數對應的下一頁的方式。

最後,Commons 模組在配置評估方式上進行了重大改進,這將顯著縮短啟動時間,尤其是在擁有大量 repository 的應用程式中。

Spring Data JPA

Spring Data JPA 模組主要進行了內部改進,並在與 JPA 和 CDI 互動方面增加了新特性:我們升級到 EclipseLink 2.5.1 並改進了與 Hibernate 4.3 的相容性,以確保我們的使用者可以使用基於 JPA 2.1 的持久化提供程式。

EntityManager 的建構函式注入

一個被反覆請求的功能也進入了這個版本:在設計應用程式元件時,將 EntityManager 例項注入到建構函式中的能力。如果您編寫需要訪問 JPA EntityManager 的類,通常使用 @PersistenceContext 來觸發它的注入。然而,我們通常認為建構函式注入是最佳實踐,原因多種多樣,因此無需對 EntityManager 回退到欄位注入將非常有用。

不幸的是,@PersistenceContext 註解目前不能用於建構函式引數。我已為此在 JPA bug tracker 中提交了一個工單,但我們肯定不必等到 JPA 2.2 釋出才能看到這個功能。從 Spring Data JPA 1.5 版本開始,您將能夠像這樣編寫應用程式元件

class UserRepositoryImpl implements UserRepositoryCustom {
    
    private final EntityManager em;

    @Autowired // or @Inject
    public UserRepositoryImpl(EntityManager em) {
        this.em = em;
    }

    …
}

預設情況下,我們將注入由您的 ApplicationContext 中宣告的 EntityManagerFactoryBean 建立的 EntityManager 例項。如果您定義了多個,可以使用 @Qualifier 指向您希望從中獲取 EntityManagerEntityManagerFactoryBean 的 bean 名稱。

CDI 環境中的 Repository 立即例項化

在 Spring 容器中使用 Spring Data repository 時,repository 會被立即例項化。甚至在 Codd 之前,它們也會在客戶端元件透過注入點請求 repository 時立即例項化。因此,無論何時將 repository 注入到客戶端中,您都可以確保獲得一個完全初始化的應用程式元件,這正是 Spring 元件模型所保證的。

然而,在 CDI 世界中,情況略有不同。當您訪問應用程式元件時,無法保證其依賴項已初始化,因為在 CDI 元件模型中,僅注入一個代理並在首次使用時觸發實際例項建立是允許的。

實際上,這可能導致 Spring Data repository 在您的應用程式程式碼正在執行 JPA 事務時被例項化。repository 例項化的一部分是檢查支援查詢方法的 JPA 命名查詢。根據 JPA 規範,此類命名查詢不存在(這在 Spring Data 環境中是完全正常的狀態)必須透過丟擲異常來表示,並且根據定義,此異常必須在 JPA 中觸發事務回滾。

這意味著在 CDI 中將應用程式元件初始化與正在執行的業務程式碼混合在一起,您可能會在前者被呼叫時破壞後者。不幸的是,在 CDI 中沒有開箱即用的方法可以強制應用程式元件立即例項化。有一些特定於容器的方法,但沒有一個可以在所有容器上可靠地工作(如果您找到了,我會非常感興趣)。

在 Spring Data JPA 1.5 中,我們將提供一個 @Eager 註解,它將使我們的 CDI 擴充套件觸發 repository 的例項化,從而避免應用程式元件建立與業務程式碼執行之間的重疊。

Spring Data REST

Spring Data REST 的核心變更在於模組的對映配置和自定義部分的重大重構。這還包括我們為單個資源暴露的預設關係型別的更改。

對於每個 repository,Spring Data REST 都暴露了一個遵循集合資源模式的專用 REST 資源。這意味著我們有一個專門用於實體集合的資源,以及集合中每個專案的單獨資源。

由於規範的 REST 客戶端不應該自行建立與之互動的 URI,而是應該使用超媒體來遵循伺服器提供的連結,我們需要暴露兩種不同的關係型別來指示集合資源和專案資源之間的區別。

從 Spring Data REST 2.0 開始,專案資源的關係型別派生自 repository 管理的域類的名稱。集合資源的關係型別然後透過使用 Evo Inflector 庫將專案資源關係型別複數化來派生。因此,對於管理 Order 例項的 repository,您將看到名為 orders 指向集合資源和名為 order 指向專案資源的連結。

關係型別的這一變化對於基於 Spring Data REST 1.x 服務的超媒體客戶端來說是突破性的改變,這是模組版本提高到 2.0 的主要原因之一。另一方面,隨著模組 M1 版本的釋出,我們已將 HAL 作為 Spring Data REST 暴露的預設媒體型別。我們正在研究對其他超媒體格式的支援,例如 Collection+JSON 等,但 HAL 似乎獲得了相當多的關注。亞馬遜最近釋出了他們的 AppStream REST API,並使用 HAL 作為表示格式。

Spring Data Neo4j / MongoDB

Spring Data Neo4j 模組中最大的變化(以及因此版本號變為 3.0 的原因)是對 Neo4j 2.0 的支援。因此,為了從該版本的最新和最佳特性中獲益,請務必嘗試 Codd 釋出候選版。

在 MongoDB 方面,最重要的一個新特性是在聚合框架中支援 Spring Expression language。如果您錯過了,Spring Data 工程師 Thomas Darimont 在他詳細的部落格文章中介紹了我們在 Codd M1 中已釋出的所有特性。

如上所述,當然,Codd 中引入的 Spring Data Commons 的所有新特性也都會體現在 Neo4j 和 MongoDB 模組中。

展望

GA 版本計劃於 2014 年 2 月底釋出。我們在 Spring Data Commons wiki 中有一個精心整理的變更日誌,列出了本次釋出中引入的所有重要特性。

我們非常感謝任何釋出前測試以及在我們的 JIRA 例項中報告發現的潛在問題。

訂閱 Spring 電子報

訂閱 Spring 電子報,保持聯絡

訂閱

領先一步

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

瞭解更多

獲取支援

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

瞭解更多

近期活動

檢視 Spring 社群的所有近期活動。

檢視全部