文章目录

Spring Framework 4.1 的release已经有一阵子了,今天终于有点时间,看了下新特性中对于静态资源的灵活处理和转换,同时基于这种处理也提供了一种体验更好的开发方式,让我觉得非常兴奋。 先来看下对于这个新特性中的核心功能, ResourceResolversResourceTransformers

  1. ResourceResolvers用来将内部的URL解析为用户能够访问的外部公共的URL(ResourceResolver接口定义的是双向的解析)。
  2. ResourceTransformers用来修改资源的内容。

这两个功能相结合,不禁让我想起了Rails的Sprockets。Sprockets主要进行三项工作,资源文件的合并,压缩,以及对高级语言的预编译(coffeescript,sass)。那么Spring的这个特性是另外一个pipeline吗? 官方博客给出的解释是这样的,

在Spring Framework 4.1中,我们使用依赖于优化的路径,这种优化在构件时使用最好的外部工具,在运行时使用Resolvers 和和Transformers 。

比如说,我们可以用yeoman,grunt,bower搭建一个面向前端开发者的项目,在开发阶段,利用ResourceResolvers直接引用工程源代码的资源路径。在生产环境,再引用经过其他工具优化过的构建完成的资源。正式通过这种方式带给了我们一种全新的开发体验。 Spring为这两个类提供了一些默认的实现类。


























类名目标
PathResourceResolver在配置的路径下查找匹配请求路径的资源
CachingResourceResolver从缓存实例中解析资源并且代理给下一个解析器
GzipResourceResolver当客户端支持gzip压缩时,查找资源的.gz扩展名形式的资源
VersionResourceResolver解析包含版本字符串的请求, 这个解析器通过改变资源的URL来设置HTTP缓存策略时很有用





















类名目标
CssLinkResourceTransformer修改CSS文件中得链接来匹配应该暴露给客户端的公共URL
CachingResourceTransformer缓存transformations的结果或者代理给下一个Transformer
AppCacheManifestTransfomer帮助处理HTML5离线应用的AppCache清单内的文件

最后来看点例子。 首先是目录结构, Spring Resource Handling showcase application

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

这样的项目结构有两个好处,

  1. 更好的开发体验,因为在开发阶段引用的是源代码。
  2. 生产环境中优化的性能,静态资源通过构建得以优化并且打包为webJar。

配置实例

1. 注册Resolver和Transformer

AppCacheManifestTransformer appCacheTransformer = new AppCacheManifestTransformer();
VersionResourceResolver versionResolver = new VersionResourceResolver()
.addFixedVersionStrategy(version, "/**/*.js")
.addContentVersionStrategy("/**");

registry.addResourceHandler("/**")
.addResourceLocations(location)
.setCachePeriod(cachePeriod)
.resourceChain(useResourceCache)
.addResolver(versionResolver)
.addTransformer(appCacheTransformer);

2. 手动解析

ResourceUrlProvider.getForLookupPath()

3. 注册

ResourceUrlEncodingFilter,调用Response的encodeURL进行解析

@Bean
public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
ResourceUrlEncodingFilter filter = new ResourceUrlEncodingFilter();

return filter;
}

ResourceUrlEncodingFilter是一个包装HttpServletResponse的过滤器,它覆盖了{HttpServletResponse#encodeURL(String) encodeUR} 方法,将内部URL转换为外部的公共URL。其内部也是使用了ResourceUrlProvider来进行转换的。

ResourceUrlProvider是获取外部URL路径的转换的核心组件,其内部定了Map<String, ResourceHttpRequestHandler> handlerMap用来进行链式的解析。

ResourceHttpRequestHandler是<mvc:resource /> 标签的具体实现,4.1版本ResourceHttpRequestHandler内部使用ResourceResolver以及ResourceTransformer来进行解析处理。

文章目录
Fork me on GitHub