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 社区所有即将举行的活动。

查看所有