领先一步
VMware 提供培训和认证,以加速你的进步。
了解更多这篇文章是我之前关于 JSR-107 的文章 的后续。添加 JSR-107 支持使我们有机会回顾我们自己的抽象,并了解两者如何和谐共存。Spring 4.1 还包含社区报告的一系列改进。
我还要高兴地宣布,一个专门针对缓存抽象的新入门指南已经发布,请查看 使用 Spring 缓存数据!
我们在 JSR-107 中发现的一个最棒的功能是在运行时解析要使用的缓存,即基于实际的方法执行。到目前为止,我们自己的支持依赖于在注解(或方面定义)级别指定缓存名称。一些问题被提出,报告说当使用多个 CacheManager
时,需要能够自定义将这些名称解析到的管理器。
我们最终做的是创建了一个类似的 CacheResolver
抽象来提供最灵活的选项。正如你可能猜到的,默认实现接受一个 CacheManager
并基于提供的缓存名称解析要使用的缓存。由于不再需要这样的名称,Spring 4.1 允许你编写以下代码
@Cacheable
public Book findBook(ISBN isbn) {...}
当然,你必须指定你自己的 CacheResolver
,它知道如何处理这个特定的调用,或者你需要以不同的方式提供要使用的缓存(继续阅读)。
就像注解的 value
属性不再是必需的一样,只要设置了 CacheResolver
,就可以省略 CacheManager
。如果你以不同的方式管理你的 Cache
实例,你实际上可以有一个不依赖于 CacheManager
的实现。
社区还报告说,他们希望能够以更细粒度的方式控制缓存行为。Spring 4.1 允许你为每个操作指定要使用的 CacheResolver
(或 CacheManager
)和 KeyGenerator
。
例如,以下代码将自定义 KeyGenerator
应用于该特定操作
@Cacheable(value="book", keyGenerator="myKeyGenerator")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
这将查找名为 myKeyGenerator
的 KeyGenerator
bean。CacheManager
和 CacheResolver
实例可以通过类似的方式设置。
另一个社区反馈是能够在方法级别共享这些自定义,**而无需**启用任何默认的缓存行为。满足 @CacheConfig
,它在类级别提供相同的自定义,即缓存名称、CacheResolver
(或 CacheManager
)和 KeyGenerator
。
@CacheConfig(cacheNames="book", keyGenerator="myKeyGenerator")
public class BookRepository {
@Cacheable
public Book findBook(ISBN isbn) {...}
public Book thisIsNotCached(String someArg) {...}
}
我们在实现 JSR-107 支持时的一个主要目标是利用我们自己抽象中已经存在的内容,以便现有应用程序能够以非常平滑的方式进行转换。JCache 支持实际上在内部使用 Spring 的缓存抽象,这允许你重用现有的缓存基础设施以及标准注解。当你指定 JSR-107 自定义组件(例如 javax.cache.annotation.CacheResolver
或 javax.cache.annotation.CacheKeyGenerator
)时,我们使用适配器将其通过我们的抽象进行路由。
具体来说,这意味着你可以保留现有的基础设施并选择你想要的任何机制。例如,你可以使用 ConcurrentMapCacheManager
,它在幕后使用 ConcurrentHashMap
以及标准的 JSR-107 注解。
如果你想尝试一下,请查看 此指南的分支,它使用 JCache 而不是 Spring 注解(提交 32fea97 显示了实际更改的内容)
Spring 4.1 预计将在今年夏天发布,它将对其缓存抽象进行重大增强;添加对 JSR-107 的支持帮助我们进一步改进了它。本文未涵盖其他一些小的增强功能,例如更好的异常处理和 Cache
接口上的便捷 putIfAbsent
方法。
与往常一样,我们欢迎社区反馈,请尝试这些功能并让我们知道你是否遇到任何问题。