Java Caching JSR107介绍(五)(一)

2014-11-24 01:37:33 · 作者: · 浏览: 3

缓存条目Listener

事件与Listener

JCache中定义了缓存事件的抽象类CacheEntryEvent ,以及事件类型EventType枚举类,包括了四种事件类型,定义见下:

public enum EventType {

CREATED, //创建

UPDATED, //更新

REMOVED, //删除

EXPIRED //过期

}

这些事件将被传播到注册在Cache中的CacheEntryListener,这个接口是一个标记接口,与四种事件类型对应的Listener接口都继承了这个接口,分别是CacheEntryCreatedListener、CacheEntryUpdatedListener、CacheEntryRemovedListener和CacheEntryExpiredListener。

Listener的注册

Listener并不一定是在Cache的进程内的,为了避免可能不支持序列化实例的注册,需要使用CacheEntryListenerConfigurations(具体类MutableCacheEntryListenerConfiguration)。

开发可在配置时通过MutableConfiguation.addCacheEntryListenerConfiguration方法增加缓存的Listener配置,或在运行期通过Cache.registerCacheEntryListener方法来注册Listener。Listener可以通过Cache.deregisterCacheEntryListener方法来注销注册。

多个CacheEntryListenerConfiguration可以增加到Configuration中,当缓存初始化时,它使用注册的Factory来创建CacheEntryListener。针对一个缓存可以存在多个Listener对应相同或者不同的EventType。在Listener创建或在其间派发事件,框架并不能保证其先后顺序。

Listener的调用

缓存Listener

●在缓存条目变化后被触发。

●在同步方式,对于一个给定的键,以该事件发生的顺序触发Listener,并阻塞调用线程,直到Listener返回。

●在异步方式,以未定义的顺序遍历多个事件,但针对相同的Key,事件必须按照发生的顺序进行处理。

Listener是观察者模式,同时Listener抛出一个异常并不会导致缓存操作失败。

在一个Listener中修改缓存的值可能会导致死锁,检测和响应死锁是特定于实现的。

缓存实现中已注册的Listener针对每个事件将最多被调用一次。

一个Listener并不一定在事件发生的进程内执行,在分布式环境中Listener可以在任何地方实现。

Listener可以有一个CacheEntryEventFilter,通过CacheEntryListenerConfiguration来配置。

Filter和同样Listener,它并不一定在事件发生的进程内执行。在分布式环境中,Filter可能实现在任何能提供最好性能的节点处。

下表总结了由每个缓存操作调用的Listener操作。条件是在操作前的条目的状态,过期始终是“否”,过期的确切时间基于缓存的特定实现。

方法

创建

过期

删除

更新

boolean containsKey(K key)

V get(K key)

是, 如果是通过read-through创建

Map getAll(Collection keys)

是, 如果是通过read-through创建

V getAndPut(K key, V value)

是,如果不存在

是,如果存在

V getAndRemove(K key)

是,如果存在

V getAndReplace(K key, V value)

是,如果存在

T invoke(K key, EntryProcessor entryProcessor);

是, 如果调用setValue()创建或者 调用getValue()通过read-through创建

是, 如果调用remove()

是, 如果调用 setValue() 更新

Map invokeAll(Set keys,

EntryProcessor entryProcessor, Object... arguments);

是, 如果调用setValue()创建或者 调用getValue()通过read-through创建

是, 如果调用remove()

是, 如果调用 setValue() 更新

Iterator > iterator()

是, 如果调用remove()

void loadAll(Set keys,boolean replaceExistingValues,

CompletionListener completionListener);

是,如果不存在

是,如果存在

void put(K key, V value)

是,如果不存在

是,如果存在

void putAll(Map map)

是,如果不存在

是,如果存在

boolean putIfAbsent(K key, V value)

是,如果不存在

boolean remove(K key)

是,如果存在

boolean remove(K key, V oldValue)

是,如果存在并且相等

void removeAll()

是,如果存在

void removeAll(Set keys)

是,如果存在

boolean replace(K key, V value)

是,如果存在

boolean replace(K key, V oldValue, V newValue)

是,如果存在并且相等

缓存条目执行器

一个javax.cache.Cache.EntryProcessor是一个可调用的功能,就像一个java.util.concurrent.Callable,应用程序可以用它来有效地执行组合的原子性的缓存操作,包括访问,更新和缓存条目,而不需要显式的锁或事务。

例如,可能希望检查一个缓存条目的值,计算出新的值,更新条目,并返回一些其他的值的原子操作,一个应用程序可以使用自定义的EntryProcessor实现来完成此功能。

javax.cache.Cache.EntryProcessor定义见下:

public interface EntryProcessor {

/**

* 处理一个条目。

* @param entry 缓存条目

* @param arguments 处理的参数集合

* @return 处理的结果

*/

T process(Cache.MutableEntry entry, Object... arguments);

}

为了在缓存条目上调用EntryProcessor,应用必须使用Cache.invoke方法调用单个key的处理器及使用Cache.invoke