I know the ehcache framework allows you to register callback methods that will be executed when a cache event occurs. I am using JMS Replicated caching which perfectly works without a custom CacheEventListenerFactory
.
However, I cannot find a proper way to implement the CacheEventListenerFactory
class so that I can handle the cache update, removed, eviction events.
So far I have tried implementing a wrapper over CacheEventListener
so that the ehcache framework can use it and invoke the callback on cache events.
public class ExtendedCacheReplicatorFactory extends JMSCacheReplicatorFactory {
@Override
public CacheEventListener createCacheEventListener(Properties properties) {
CacheEventListener cacheEventListener = super
.createCacheEventListener(properties);
return new ExtendedCacheEventListener(cacheEventListener);
}
class ExtendedCacheEventListener implements CacheEventListener {
private CacheEventListener cacheEventListener;
public ExtendedCacheEventListener(CacheEventListener cacheEventListener) {
this.cacheEventListener = cacheEventListener;
}
@Override
public void notifyRemoveAll(Ehcache cache) {
Logger.info(this, "All removed...");
cacheEventListener.notifyRemoveAll(cache);
}
@Override
public void notifyElementUpdated(Ehcache cache, Element element)
throws CacheException {
Logger.info(this, "Element updated..." + element.getObjectKey());
cacheEventListener.notifyElementUpdated(cache, element);
}
@Override
public void notifyElementRemoved(Ehcache cache, Element element)
throws CacheException {
Logger.info(this, "Element removed..." + element.getObjectKey());
cacheEventListener.notifyElementRemoved(cache, element);
}
@Override
public void notifyElementPut(Ehcache cache, Element element)
throws CacheException {
Logger.info(this, "Element put..." + element.getObjectKey());
cacheEventListener.notifyElementPut(cache, element);
}
@Override
public void notifyElementExpired(Ehcache cache, Element element) {
Logger.info(this, "Element expired..." + element.getObjectKey());
cacheEventListener.notifyElementExpired(cache, element);
}
@Override
public void notifyElementEvicted(Ehcache cache, Element element) {
Logger.info(this, "Element evicted..." + element.getObjectKey());
cacheEventListener.notifyElementEvicted(cache, element);
}
@Override
public void dispose() {
Logger.info(this, "disposing..");
cacheEventListener.dispose();
}
public Object clone() throws CloneNotSupportedException {
Logger.info(this, "clone..");
super.clone();
return new ExtendedCacheEventListener(
(CacheEventListener) cacheEventListener.clone());
}
}
}
Following is my ehcache.xml configuration.
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
<diskStore path="java.io.tmpdir" />
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.jms.JMSCacheManagerPeerProviderFactory"
properties="initialContextFactoryName=com.example.ehcache.credentialsdserver.ActiveMQInitialContextFactoryImpl,
providerURL=tcp://localhost:61616,
replicationTopicConnectionFactoryBindingName=topicConnectionFactory,
replicationTopicBindingName=ehcache,
getQueueConnectionFactoryBindingName=queueConnectionFactory,
getQueueBindingName=ehcacheGetQueue,
topicConnectionFactoryBindingName=topicConnectionFactory,
topicBindingName=ehcache"
propertySeparator="," />
<defaultCache eternal="true"
maxElementsInMemory="100"
overflowToDisk="false" />
<cache name="credentials"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000"
eternal="false"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<cacheEventListenerFactory
class="com.example.ehcache.credentialsdserver.ExtendedCacheReplicatorFactory"
properties="replicateAsynchronously=true,
replicatePuts=true,
replicateUpdates=true,
replicateUpdatesViaCopy=true,
replicateRemovals=true,
asynchronousReplicationIntervalMillis=1000"
propertySeparator="," />
<cacheLoaderFactory
class="net.sf.ehcache.distribution.jms.JMSCacheLoaderFactory"
properties="initialContextFactoryName=com.example.ehcache.credentialsdserver.ActiveMQInitialContextFactoryImpl,
providerURL=tcp://localhost:61616,
replicationTopicConnectionFactoryBindingName=topicConnectionFactory,
getQueueConnectionFactoryBindingName=queueConnectionFactory,
replicationTopicBindingName=ehcache,
getQueueBindingName=ehcacheGetQueue,
timeoutMillis=10000" />
</cache>
Am I going in a right direction or am I missing something here?
The question is how to implement the CacheEventListenerFactory
and CacheEventListener
with JMS Replication so that the cache events can be intercepted and handled in my custom implementation?