Spring Framework 4.1 - 处理静态 Web 资源

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

本周,Juergen 宣布了 Spring Framework 4.1 发布候选版本。现在是时候测试这些新功能,看看它们如何让您的应用程序变得更好!

其中一个新特性是静态 Web 资源的灵活解析和转换。Spring 框架已经允许您使用 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 中,我们选择了一条道路,即在构建时使用现有最适合您的应用程序的工具优化资源,并在运行时利用 Resolvers 和 Transformers。对于 JavaScript 应用程序,我们希望利用 JavaScript 开发人员使用的相同工具链,如 gruntgulp,在构建时优化资源。Dart 和 TypeScript 也是如此——原生工具总是提供最佳体验。

这些生态系统非常丰富(实际上比 Java 中可用的选项丰富得多),并且不断发展。我们相信依赖这些生态系统以及框架中的灵活解决方案是这里最好的方法。

因此,您的应用程序应该找到正确的平衡并利用

  • 在构建时使用客户端应用程序的原生工具进行转译、精简、合并等任务
  • 框架提供的解析器和转换器(您也可以创建自己的!)

着眼于即将到来的标准,例如 HTTP/2ECMAScript 6,这变得更有意义了——未来几年内,这个领域将发生决定性的变化。

资源版本控制

静态 Web 资源的版本控制是将 Web 应用程序推送到生产环境时的核心问题,并且在很大程度上是一个服务器端问题。Spring Framework 4.1 旨在通过各种策略提供一流的支持,包括基于内容的哈希(如 Git 中,也称为指纹识别)以及适用于整套文件的版本(例如,与JavaScript 模块加载器一起工作时所需的)。

所有这些背后的思想是“缓存失效”,即资源以激进的 HTTP 缓存指令(例如,缓存一年)提供,并在必要时依赖 URL 中与版本相关的更改来“打破”缓存。这可以是内容哈希版本,它在文件内容更改时发生变化,也可以是通过其他方式确定的版本(例如,简单属性、git commit sha 等)。

源代码布局

另一个非常重要的问题是您的源代码位于何处以及您的应用程序如何组织——作为 Java 开发人员,我们习惯于在 src/main/webapp 中找到它们。但这真的是最好的位置吗?

如今,大多数 Web 应用程序由在浏览器中运行的客户端应用程序和服务器应用程序组成,两者通过 HTTP 或 websockets 进行通信。每个应用程序都可以有自己的依赖项、测试、构建工具等。那么,为什么我们不能将它们解耦并在我们的代码库中体现这种关注点分离呢?

将您的 Web 应用程序分解为模块——一个客户端模块和一个服务器模块——可以显著改善您的开发体验,并赋予您的应用程序所需的自由度。

我们在 Project Sagan 中使用了相同的布局,我在之前的一个截屏视频《Project Sagan: 客户端架构》中详细讨论了这背后的原理。

这里是一个项目布局示例

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

Resolvers/Transformers 和构建工具都可以提供围绕资源处理的类似功能。那么我们应该使用哪一个呢?

Spring Resource Handling 演示应用程序

Spring Resource Handling 演示应用程序中,我们展示了一些关键特性

  • 在 HTML 响应、CSS 文件和 HTML5 appcache manifests 中使静态资源缓存失效
  • 如前所述的新的项目布局
  • 模板引擎集成,例如Groovy markup templatesHandlebars
  • 使用 LESS 作为 CSS 替代品,在开发时使用客户端预处理器,生产时使用构建处理器
  • 一套完整的构建工具链,使用 Gradle 和 gulp;未来的示例可以使用 grunt、maven 等展示相同的功能

注意,这种新的项目布局有两个关键优势

  1. 更好的开发者体验,因为在开发时资源未优化,直接从磁盘提供

  2. 生产中的最佳性能,因为静态资源由构建优化并打包在 webJAR 中——因此它们最终在生产中从类路径提供

我们期待您的反馈

Spring Resource Handling 演示应用程序仍在进行中,我们正在准备增强功能以简化配置(请参阅 SPR-11982);当然,社区的反馈将非常有帮助。

欲了解更多,不要错过在得克萨斯州达拉斯举行的SpringOne 2GX 2014——Rossen 和我将在一个专题会议中介绍这个主题。

订阅 Spring 通讯

订阅 Spring 通讯,保持联系

订阅

先行一步

VMware 提供培训和认证,为您的进步加速。

了解更多

获取支持

Tanzu Spring 通过一个简单的订阅提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看全部