Spring Framework 4.1 - 處理靜態 Web 資源

工程 | Brian Clozel | 2014 年 7 月 24 日 | ...

本週,Juergen 釋出了 Spring Framework 4.1 的釋出候選版。現在是時候測試這些新功能,看看它們如何讓您的應用程式變得更好!

這些新功能之一就是對靜態 Web 資源的靈活解析和轉換。Spring Framework 已經允許您使用 ResourceHttpRequestHandlers 來提供靜態資源。此功能為您提供了更大的強大功能和新的可能性。

ResourceResolvers 和 ResourceTransformers

ResourceResolversResourceTransformers 是這項新功能的核心。

ResourceResolvers 可以解析資源,給定它們的 URL 路徑。它們還可以解析面向外部的公共 URL 路徑供客戶端使用,給定內部資源路徑。ResourceTransformers 可以修改已解析資源的內容。

這是一個圖表示例,說明了在使用 ResourceHttpRequestHandlers 提供靜態資源時發生的情況

  Request for Resource
      |
      | HTTP request
      v
  Resolvers chain: FirstResolver, SecondResolver, ThirdResolver
  (each resolver can return the resource or delegate to the next one)
      |
      | Resolved Resource
      v
  Transformers chain: FirstTransformer, SecondTransformer
  (each transformer can transform the resource or just pass it along without modification)
      |
      | Transformed Resource
      v
  HTTP Response with Resource content

這是另一個圖,展示了 ResourceResolvers 鏈如何更新資源的連結供 HTTP 客戶端使用

  Resource link in a template source file
      |
      | Resource path (like "/css/main.css")
      v 
  Resolvers chain: FirstResolver, SecondResolver, ThirdResolver
  (each resolver can modify the resource path or delegate to the next one)
      |
      | Updated resource path (like "/css/main-0e37f12.css")
      v 
  Resource link in a rendered template 

現在,讓我們看看 ResourceResolvers 的實現提供了哪些功能

解析器名稱 目標
PathResourceResolver 在配置的位置(類路徑、檔案系統...)下查詢與請求路徑匹配的資源
CachingResourceResolver 從 Cache 例項解析資源或委託給鏈中的下一個解析器
GzipResourceResolver 當 HTTP 客戶端支援 gzip 壓縮時,查詢具有 ".gz" 副檔名的資源的變體
VersionResourceResolver 解析包含版本字串的請求路徑,即所請求資源的版本資訊。此解析器透過更改資源的 URL 來設定 HTTP 快取策略,這在資源更新時非常有用。

現在,讓我們來看看 ResourceTransformers

轉換器名稱 目標
CssLinkResourceTransformer 修改 CSS 檔案中的連結,使其與應暴露給客戶端的公共 URL 路徑匹配
CachingResourceTransformer 將轉換結果快取到 Cache 或委託給鏈中的下一個轉換器
AppCacheManifestTransfomer 幫助處理 HTML5 離線應用程式的 HTML5 AppCache manifest 中的資源

這些對 ResourceHttpRequestHandlers 的新新增功能的主要目標是,讓開發者能夠輕鬆地最佳化和處理經過最佳化的靜態資源,以提高 前端效能

又一個資產管道?

許多庫和框架透過完整、整合的資產管道來解決這些問題,這些管道通常對所使用的程式語言、技術和專案結構提供強有力、有主見的解決方案。這些資產管道負責在建立可部署應用程式時和/或應用程式執行時進行資源最佳化。

在 Spring Framework 4.1 中,我們選擇了一條路徑,該路徑依賴於使用現有最佳工具在構建時最佳化資源,並在執行時利用解析器和轉換器。對於 JavaScript 應用程式,我們希望利用 JavaScript 開發人員使用的相同工具鏈,例如 gruntgulp 在構建時最佳化資源。對於 DartTypeScript 也是如此——原生工具始終提供最佳體驗。

這些生態系統非常豐富(實際上比 Java 中可用的選項豐富得多)並且不斷發展。我們相信依賴於這些生態系統和框架中的靈活解決方案是最佳方法。

因此,您的應用程式應該找到正確的平衡點並利用

  • 在構建時使用客戶端應用程式的原生工具進行轉譯、最小化、連線……等任務
  • 框架提供的解析器和轉換器(也可以建立您自己的!)

放眼未來的標準,例如 HTTP/2ECMAScript 6,這使得——在接下來的幾年裡,這個領域的變化將變得更加重要。

資源版本控制

靜態 Web 資源的 버전控制是將 Web 應用程式推送到生產環境時的核心關注點,也是一個非常重要的伺服器端關注點。Spring Framework 4.1 旨在透過各種策略提供一流的支援,包括基於內容的雜湊(如 Git 中,也稱為指紋識別)以及適用於整個檔案集的版本(例如,對於使用 JavaScript 模組載入器 是必需的)。

這一切的基礎是“快取破壞”的概念,即資源會以積極的 HTTP 快取指令(例如,未來 1 年)提供,並在必要時依賴於 URL 中與版本相關的更改來“破壞”快取。這可能是一個基於內容的雜湊版本,當檔案內容更改時就會更改,或者是一個透過其他方式確定的版本(例如,簡單的屬性、git 提交 sha 等)。

原始碼佈局

另一個非常重要的問題是你的原始碼在哪裡以及你的應用程式是如何組織的——作為 Java 開發人員,我們習慣於在 src/main/webapp 中找到它們。但這真的是最好的位置嗎?

如今,大多數 Web 應用程式都由在瀏覽器中執行的客戶端應用程式和伺服器應用程式組成,它們透過 HTTP 或 websockets 進行通訊。其中每個應用程式都可以有自己的依賴項、測試、構建工具等。那麼,為什麼我們不能將它們解耦,並在程式碼庫中反映這種關注點分離呢?

將 Web 應用程式分解為模組——一個客戶端模組和一個伺服器模組——可以極大地改善您的開發體驗,並賦予應用程式所需的自由。

我們在 Project Sagan 中使用了相同的佈局,並在之前的螢幕錄影 Project Sagan: client-side architecture 中詳細討論了其背後的原因。

這是專案佈局的一個示例

spring-app/
|- build.gradle
|- client/
|  |- src/
|  |  |- css/
|  |  |- js/
|  |     |- main.js
|  |- test/
|  |- build.gradle
|  |- gulpfile.js
|- server/
|  |- src/main/java/
|  |– build.gradle

解析器/轉換器和構建工具都可以提供類似的資源處理功能。那麼我們應該使用哪一個呢?

Spring Resource Handling 示例應用程式

Spring Resource Handling 示例應用程式 中,我們演示了幾個關鍵功能

  • 快取破壞 HTML 響應、CSS 檔案和 HTML5 appcache manifest 中的靜態資源
  • 一個新專案佈局,如前所述
  • 模板引擎整合,例如 Groovy markup templatesHandlebars
  • 使用 LESS 作為 CSS 的替代品,在開發過程中使用客戶端預處理器,在生產環境中則使用構建處理器
  • 完整的構建工具鏈,使用 Gradle 和 gulp;未來的示例可以演示使用 grunt、maven 等的相同功能

請注意,這個新的專案佈局有兩個主要優點

  1. 更好的開發體驗,因為在開發時,資源是未最佳化的,直接從磁碟提供

  2. 生產環境的最佳效能,因為靜態資源由構建工具最佳化並打包到 webJAR 中——因此它們最終在生產環境中從類路徑提供

我們期待您的反饋

這個 Spring Resource Handling 示例應用程式 仍在開發中,我們正在準備增強功能以便於配置(參見 SPR-11982);當然,社群的反饋在這裡將非常有用。

欲瞭解更多資訊,請不要忘記 2014 年 SpringOne 2GX 大會(德克薩斯州達拉斯)——我和 Rossen 將在一次專門的會議上涵蓋這個主題。

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

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

瞭解更多

獲得支援

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

瞭解更多

即將舉行的活動

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

檢視所有