日期:2014-05-16  浏览次数:20332 次

Java Caching JSR107介绍(五)

缓存条目Listener

事件与Listener

JCache中定义了缓存事件的抽象类CacheEntryEvent<K,V>,以及事件类型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<K,V> getAll(Collection<? extends K> keys)

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

V getAndPut(K key, V value)

是,如果不存在

是,如果存在

V getAndRemove(K key)

是,如果存在

V getAndReplace(K key, V value)

是,如果存在

<T> T invoke(K key, EntryProcessor<K, V> entryProcessor);

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

是, 如果调用remove()

是, 如果调用 setValue() 更新

<T> Map<K, T> invokeAll(Set<? e