先行一步
VMware 提供培训和认证,为您的进步加速。
了解更多本周,Juergen 宣布了 Spring Framework 4.1 发布候选版本。现在是时候测试这些新功能,看看它们如何让您的应用程序变得更好!
其中一个新特性是静态 Web 资源的灵活解析和转换。Spring 框架已经允许您使用 ResourceHttpRequestHandlers
提供静态资源。此功能为您提供了更多能力和新的可能性。
ResourceResolvers
和 ResourceTransformers
是此新功能的核心。
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 开发人员使用的相同工具链,如 grunt 和 gulp,在构建时优化资源。Dart 和 TypeScript 也是如此——原生工具总是提供最佳体验。
这些生态系统非常丰富(实际上比 Java 中可用的选项丰富得多),并且不断发展。我们相信依赖这些生态系统以及框架中的灵活解决方案是这里最好的方法。
因此,您的应用程序应该找到正确的平衡并利用
着眼于即将到来的标准,例如 HTTP/2 和 ECMAScript 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 演示应用程序中,我们展示了一些关键特性
注意,这种新的项目布局有两个关键优势
更好的开发者体验,因为在开发时资源未优化,直接从磁盘提供
生产中的最佳性能,因为静态资源由构建优化并打包在 webJAR 中——因此它们最终在生产中从类路径提供
Spring Resource Handling 演示应用程序仍在进行中,我们正在准备增强功能以简化配置(请参阅 SPR-11982);当然,社区的反馈将非常有帮助。
欲了解更多,不要错过在得克萨斯州达拉斯举行的SpringOne 2GX 2014——Rossen 和我将在一个专题会议中介绍这个主题。