Hazelcast系列(二):hazelcast集成(嵌入式)
Hazelcast系列(三):hazelcast集成(服务器/客户端)
Hazelcast系列(五):Auto-Detection发现机制
通过?Hazelcast系列(九):Map(一)加载和存储?对 Map 从数据库中加载方式以及存储数据方式有个大概了解,续接上文,咱们继续对 Map 的其他方面进行探讨。
Map 内容相关文章:
Hazelcast系列(九):Map(一)主要探讨 Map 加载、存储以及配置
Hazelcast系列(十):Map(二)主要探讨 Map 监听器、拦截器
Hazelcast系列(十一):Map(三)主要探讨 Map 备份、过期和驱逐以及内存格式
接下来,咱们来认识一下 Map 的 监听器 和 拦截器。
监听器?Listener 可以帮助使用者监听不同的事件进行额外的数据操作,事件例如添加数据、删除数据、更新特定数据等等。
针对于 Map 而言,事件分为基于 Map级别 的事件和基于 条目(Entry)的事件。
Map级别事件是由于Map级别的操作触发的,例如:IMap.clear()、IMap.evictAll()。
条目级别事件是由于操作某个特定条目后触发的,例如:IMap.remove()、IMap.evict()。
以下是 Map 级别和基于 条目(Entry) 的事件的监听器:
监听器名称 | 描述 |
---|---|
EntryAddedListener | 将条目添加到地图时会收到通知 |
EntryEvictedListener | 当基于大小的驱逐,从Map中删除条目时,会收到通知 |
EntryExpiredListener | 当基于过期的驱逐,从Map中删除条目时,会收到通知 |
EntryLoadedListener | 当条目通过MapLoader实现的load加载时,会收到通知 |
EntryMergedListener | 当合并WAN复制的条目时,会收到通知 |
EntryRemovedListener | 当条目直接从map删除时,会收到通知 |
EntryUpdatedListener | 当条目被更新时,会收到通知 |
EventLostListener | 当事件丢失时,会收到通知 |
MapClearedListener | 当使用Map的clear方法移除所有条目时,会收到通知 |
MapEvictedListener | 当使用Map的evictAll方法删除所有条目时,会收到通知 |
MapPartitionLostListener | 当主分区和分区所有备份都丢失了特定Map数据的时候,会收到通知 |
配置的监听器必须实现?MapListener相应子接口,例如 EntryAddedListener 或 MapClearedListener。
/**
* Hazelcast监听器
*/
public class HazelcastMapListener implements EntryAddedListener<Long, StudentPo>, EntryUpdatedListener<Long, StudentPo> {
@Override
public void entryAdded(EntryEvent<Long, StudentPo> entryEvent) {
//TODO
Long key = entryEvent.getKey();
System.out.println("监听到" + key + "添加");
}
@Override
public void entryUpdated(EntryEvent<Long, StudentPo> entryEvent) {
Long key = entryEvent.getKey();
System.out.println("监听到" + key + "更新");
}
}
方式一
HazelcastInstance hz = Hazelcast.newHazelcastInstance();
IMap<String, String> map = hz.getMap("mapcache");
//不仅仅监听本节点的事件
map.addEntryListener(new HazelcastMapListener(), true);
//仅仅监听本节点的事件
//map.addLocalEntryListener(new HazelcastMapListener());
方式二
HazelcastInstance hz = Hazelcast.newHazelcastInstance();
IMap<String, String> map = hz.getMap("mapcache");
//不仅仅监听本节点的事件
map.addEntryListener( new HazelcastMapListener(), Predicates.equal("name","xiaozi") ,true );
//仅仅监听本节点的事件
//map.addLocalEntryListener(new HazelcastMapListener(), Predicates.equal("name", "xiaozi"), true);
方式三
hazelcast:
map:
mapcache:
entry-listeners:
- class-name: com.hazelcast.hazelcastspringbootdemo1.config.HazelcastMapListener
include-value: false
local: false
? ? ? ? 这里的配置参数同编程方式的方法参数都是一样的,编程方式有些方法只不过重载了。
? ? ? ? 说明:class-name? 监听器的全限定类名
? ? ? ? ? ? ? ? ? ?include-value? 是否包含特定值的监听
? ? ? ? ? ? ? ? ? ?local? 是否只监听本节点的事件
与监听器不同,拦截器可以在 Map 操作完成之前更改对其执行的操作。使用监听器,你可以在方法完成并且内存中的映射已修改后执行操作。拦截器操作是同步的,允许你更改方法的行为、更改其值或完全取消它。
拦截器是服务端的功能。
Map 拦截器是链式的,因此多次添加相同的拦截器到同一个 Map 可能会导致重复的效果。当使用拦截器时,很容易发生这种情况。
当你以这种方式添加拦截器时,一定要实现 hashCode() 方法,以便为拦截器的每个实例返回相同的值。最好也实现 equals() 方法,因为这确保了可以可靠地删除 Map 拦截器。
IMap API 有两种向 Map 添加和删除拦截器的方法: addInterceptor 和 removeInterceptor。
方法名 | 描述 |
---|---|
interceptGet | 用新值替换返回的 map.get() 值 |
afterGet | map.get() 操作完成后采取的操作 |
interceptPut | 将 map.put() 中的值替换为新值 |
afterPut | map.put() 完成后要采取的操作 |
interceptRemove | 获取已删除的 Map 的 Entry |
afterRemove | map.remove() 完成后要采取的操作 |
配置的监听器必须实现?MapInterceptor?相应子接口
/**
* hazelcast拦截器类
*/
public class HazelcastMapInterceptor implements MapInterceptor {
/**
* 拦截get操作,可以返回其他值来替换原有值
*
* @param o
* @return
*/
@Override
public Object interceptGet(Object o) {
return o;
}
/**
* get操作执行完后被调用
*
* @param o
*/
@Override
public void afterGet(Object o) {
System.out.println("已获取的值" + o);
}
/**
* 拦截put,返回的值会设置到map中
*
* @param oldVal
* @param newVal
* @return
*/
@Override
public Object interceptPut(Object oldVal, Object newVal) {
return newVal;
}
/**
* put操作执行后被调用
*
* @param o
*/
@Override
public void afterPut(Object o) {
}
/**
* 拦截remove,返回被删除对象
*
* @param o
* @return
*/
@Override
public Object interceptRemove(Object o) {
return o;
}
/**
* remove操作执行后被调用
*
* @param o
*/
@Override
public void afterRemove(Object o) {
}
/**
* hashCode值,为每个实例返回相同的值
*
* @return
*/
@Override
public int hashCode() {
return 1956850123;
}
}
/**
* hazelcast配置类
*/
@Configuration
public class HazelcastServerConfig {
/**
* 配置类
* @return
*/
@Bean
public Config serverConfig() {
ClasspathYamlConfig yamlConfig = new ClasspathYamlConfig("hazelcast.yaml");
return yamlConfig;
}
/**
* 实例对象
* @param serverConfig
* @return
*/
@Bean
public HazelcastInstance hazelcastInstance(Config serverConfig) {
HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(serverConfig);
IMap<Object, Object> map = hazelcastInstance.getMap(HazelcastConstants.HAZECAST_MAP_CACHE);
map.addInterceptor(new HazelcastMapInterceptor());
return hazelcastInstance;
}
}
? ????????暂未找到对应的yaml配置方式,所以采用编程的方式添加
? ? ? ? ?注意:多个节点添加拦截器一定要添加hashcode方法,避免同一个拦截器被多次加入
同一份代码复制两份进行测试,开启不同的端口
环境同前面测试监听器一样
??