![]() |
3.1 缓存定义的规范 |
JSR是Java Specification Requests的缩写,意思是Java规范提案,它已成为Java界的一个重要标准。在2012年10月26日JSR规范委员会发布了JSR 107(JCache API)的首个早期规范,该规范定义了一种对Java对象临时在内存中进行缓存的方法,包括对象的创建、访问、失效、一致性等。
新规范的主要内容如下:
·为应用程序提供缓存Java对象的功能。
·定义了一套通用的缓存概念和工具。
·最小化开发人员使用缓存的学习成本。
·最大化应用程序在使用不同缓存实现之间的可移植性。
·支持进程内和分布式的缓存实现。
·支持by-value和by-reference的缓存对象。
·定义遵照JSR-175的缓存注解,定义一套Java编程语言的元数据。
从规范的设计角度来看,在javax.cache包中有一个CacheManager接口负责保存和控制一系列的缓存,主要特性包括:
·能从缓存中读取数据
·能将数据写入到缓存中
·缓存具有原子性操作
·具有缓存事件监听器
·具有缓存注解
·保存缓存的KEY和VALUE类型应该为泛型
在JSR107规范中将Cache API(javax.cache)作为实现的类库,通过如下的Maven进行引入。
<dependency> <groupId>javax.cache</groupId> <artifactId>cache-api</artifactId> <version>1.0.0</version> </dependency>
Cache API定义了4个核心概念:
·CachingProvider:定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可以在运行期访问多个CachingProvider。
·CacheManager:定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
·Cache:是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有。
·Entry:是一个存储在Cache中的key-value对。
每一个存储在Cache中的条目有一个定义的有效期,即Expiry Duration。一旦超过这个时间,条目即为过期的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。
Store-By-Value和Store-By-Reference是两种不同的缓存实现:
·Store-By-Value:指在key/value存入缓存时,将其值拷贝一份存入缓存。避免在其他程序修改key或value的值时,污染缓存内存储的内容。
·Store-By-Reference:指在key/value存入缓存时,直接将其引用存入缓存。
Java常见的堆内缓存,一般使用Store-By-Reference方式,提升缓存性能。常见的堆外缓存和进程外缓存,一般由于使用引用在技术上比较复杂,通常使用Store-By-Value方式。
如果缓存中的数据已经过期,那它将不能从缓存返回。如果缓存没有配置过期策略,默认是永久有效的策略(Eternal)。
过期策略可以在配置时提供一个ExpiryPolicy实现的设置,见下面的定义:
public interface ExpiryPolicy<K, V> { Duration getExpiryForCreatedEntry(Entry<? extends K, ? extends V>entry); Duration getExpiryForAccessedEntry(Entry<? extends K, ? extends V>entry); Duration getExpiryForModifiedEntry(Entry<? extends K, ? extends V>entry); }
其中:
·getExpiryForCreatedEntry():当数据创建后的到期持续时间;
·getExpiryForAccessedEntry():当数据访问后的到期持续时间;
·getExpiryForModifiedEntry():当数据修改后的到期持续时间。
当这些方法被调用时,ExpiryPolicy将返回下列值之一:
·持续时间等于缓存配置的过期时间;
·Duration.ZERO表明数据目前已经是过期的。
在特定的缓存操作执行后的一段时间之后数据需要进行回收,该时间由Duration类定义。Duration是由一个由java.util.concurrent.TimeUnit和时长durationAmount组成,TimeUnit的最小值为TimeUnit.MILLISECONDS。