|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
JCache (JSR-107) 注解
自 4.1 版本起,Spring 的缓存抽象完全支持 JCache 标准(JSR-107)注解:@CacheResult、@CachePut、@CacheRemove 和 @CacheRemoveAll,以及配套的 @CacheDefaults、@CacheKey 和 @CacheValue。
即使您尚未将缓存存储迁移到 JSR-107,也可以使用这些注解。
其内部实现基于 Spring 的缓存抽象,并提供了符合规范的默认 CacheResolver 和 KeyGenerator 实现。
换句话说,如果您已经在使用 Spring 的缓存抽象,则可以切换到这些标准注解,而无需更改您的缓存存储(或相应配置)。
功能摘要
对于熟悉 Spring 缓存注解的用户,下表描述了 Spring 注解与其对应的 JSR-107 注解之间的主要区别:
| Spring | JSR-107 | 备注 |
|---|---|---|
|
|
非常相似。 |
|
|
虽然 Spring 使用方法调用的结果来更新缓存,但 JCache 要求将该结果作为参数传递,并使用 |
|
|
非常相似。 |
|
|
参见 |
|
|
让你以类似的方式配置相同的概念。 |
JCache 引入了 javax.cache.annotation.CacheResolver 的概念,它与 Spring 的 CacheResolver 接口类似,不同之处在于 JCache 仅支持单个缓存。默认情况下,一个简单的实现会根据注解中声明的名称来获取要使用的缓存。需要注意的是,如果注解中未指定缓存名称,则会自动生成一个默认名称。更多信息请参见 @CacheResult#cacheName() 的 javadoc。
CacheResolver 实例由 CacheResolverFactory 获取。可以为每个缓存操作自定义该工厂,如下例所示:
@CacheResult(cacheNames="books", cacheResolverFactory=MyCacheResolverFactory.class) (1)
public Book findBook(ISBN isbn)
| 1 | 为此操作自定义工厂。 |
| 对于所有被引用的类,Spring 会尝试查找具有给定类型的 bean。 如果存在多个匹配项,则会创建一个新实例,并可以使用常规的 bean 生命周期回调方法,例如依赖注入。 |
键由 javax.cache.annotation.CacheKeyGenerator 生成,其作用与 Spring 的 KeyGenerator 相同。默认情况下,所有方法参数都会被纳入考虑,除非至少有一个参数使用了 @CacheKey 注解。这与 Spring 的自定义键生成声明类似。例如,以下两个操作是等效的,一个使用 Spring 的抽象,另一个使用 JCache:
@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
@CacheResult(cacheName="books")
public Book findBook(@CacheKey ISBN isbn, boolean checkWarehouse, boolean includeUsed)
你也可以在操作上指定 CacheKeyResolver,这与指定 CacheResolverFactory 的方式类似。
JCache 可以管理由带注解的方法抛出的异常。这不仅可以防止缓存被更新,还可以将异常本身缓存起来,作为失败的标识,从而避免再次调用该方法。假设当 ISBN 结构无效时,会抛出 InvalidIsbnNotFoundException 异常。这是一种永久性失败(使用这样的参数永远无法检索到任何图书)。以下配置会将该异常缓存起来,使得后续使用相同无效 ISBN 的调用直接抛出已缓存的异常,而不再重新调用该方法:
@CacheResult(cacheName="books", exceptionCacheName="failures"
cachedExceptions = InvalidIsbnNotFoundException.class)
public Book findBook(ISBN isbn)
启用 JSR-107 支持
你无需执行任何特定操作即可在 Spring 的声明式注解支持旁边启用 JSR-107 支持。只要类路径中同时存在 JSR-107 API 和 @EnableCaching 模块,cache:annotation-driven 注解和 spring-context-support XML 元素都会自动启用 JCache 支持。
| 根据您的使用场景,选择权基本上在您手中。您甚至可以混合搭配服务:对某些服务使用 JSR-107 API,而对其他服务使用 Spring 自带的注解。然而,如果这些服务影响的是相同的缓存,您应采用一致且相同的键生成实现。 |