36 JCacheイベントの使用

JCacheイベントを処理するイベント・リスナーを作成および登録できます。

JCacheイベント・モデルはjavax.cache.eventパッケージで定義され、Java Caching API仕様の第8章で説明されています。

この章の内容は次のとおりです。

JCacheイベントの使用の概要

JCacheイベント・モデルによって、アプリケーションはキャッシュ内のエントリの監視可能な変更を表すイベントの受信および処理が可能になります。イベント・モデルは、Javaアプリケーションで共通する標準のJavaイベントおよびイベント・リスナーの規則を使用します。

JCacheイベントは、CacheEntryEventクラスで定義されるキャッシュ・エントリに固有の標準Javaイベントです。JCacheはキャッシュ・エントリ用に4つのイベント・タイプを定義しています。

  • CREATED – キャッシュ・エントリの作成を示します。

  • UPDATED – キャッシュ・エントリの更新を示します。

  • REMOVED – キャッシュ・エントリの削除を示します。

  • EXPIRED – キャッシュ・エントリの失効を示します。

JCacheイベント・モデルはイベント・リスナー使用してイベントを処理し、すべての必要なイベントの処理を実行します。各イベント・タイプには、対応するイベント・リスナー・インタフェースがあり、必要に応じて実装できます。さらに、イベント・フィルタを使用することによって、イベントがリスナーにディスパッチされる前にイベントを処理できます。イベント・リスナーおよびフィルタは、キャッシュの構成時に静的に登録することも、キャッシュが作成された後に動的に登録することもできます。

Coherence JCacheプロバイダでは、ローカル、パーティションおよびパススルー・キャッシュのJCacheイベントの使用がサポートされています。プロバイダは、Coherence固有のMapListenerおよびMapEvent APIを活用してJCacheイベントを実装しています。アプリケーションは、基礎となるNamedCacheインスタンスに動的にアクセスしてMapListener APIを使用できますが、直接そのように使用する場合は、JCache Coherence実装によって提供される追加の動作はバイパスされます。

イベント・リスナーの作成

各イベント・タイプには、CacheEntryListenerインタフェースを拡張した対応するイベント・リスナー・インタフェースがあります。イベント・タイプ・インタフェースには、CacheEntryCreatedListenerCacheEntryUpdatedListenerCacheEntryRemovedListenerおよびCacheEntryExpiredListenerインタフェースが含まれています。単一のイベント・リスナーが複数のイベント・タイプ・リスナー・インタフェースを実装することも、複数のイベント・リスナーが同じイベント・タイプ・リスナー・インタフェースを実装することも可能です。次の例では、キャッシュにエントリが作成されるごとにイベントの詳細を含むログ・メッセージを出力するCREATEDイベントのイベント・リスナーを作成しています。

例36-1 イベント・リスナーの実装例

import java.io.Serializable;
import javax.cache.event.CacheEntryCreatedListener;
import javax.cache.event.CacheEntryEvent;
import javax.cache.event.CacheEntryListenerException;

public class MyCacheEntryListener<K, V>
   implements CacheEntryCreatedListener<K, V>, Serializable
   {
      private static final long serialVersionUID = 1L;
 
   public void onCreated(Iterable<CacheEntryEvent<? extends K, ? extends V>>
      events)
      throws CacheEntryListenerException
      {
         for (CacheEntryEvent<? extends K, ? extends V> event : events)
            {
            System.out.println("Received a " + event);
            }
      }
}

シリアライズが必要なイベント・リスナーは、POFシリアライズを使用できます。ただし、POFにはキャッシュ・プロバイダ実装間の移植性はありません。

イベント・フィルタの作成

キャッシュ・エントリ・イベント・フィルタは、イベントがエントリ・イベント・リスナーにディスパッチされる前にキャッシュ・イベントを評価する機会を提供します。イベント・フィルタを使用すると、必要に応じて追加の処理を実行できます。イベント・フィルタは、CacheEntryEventFilterインタフェースを実装する必要があります。次の例では、イベントのディスパッチを停止し、システム・メッセージを出力するCREATEDイベントのイベント・フィルタを作成しています。

例36-2 イベント・フィルタの実装例

import java.io.Serializable;
import javax.cache.event.CacheEntryEvent;
import javax.cache.event.CacheEntryEventFilter;
import javax.cache.event.CacheEntryListenerException;
import javax.cache.event.EventType;
 
public class MyCacheEntryEventFilter<K, V>
   implements CacheEntryEventFilter<K, V>, Serializable
   {
      private static final long serialVersionUID = 1L;
 
   public boolean evaluate(CacheEntryEvent<? extends K, ? extends V> event)
      throws CacheEntryListenerException
      {
         boolean result = false;
 
         if (event.getEventType() == EventType.CREATED)
            {
            System.out.println("filter event=" + event + " filter result=" +
               result);
            }
 
         return result;
      }
}

シリアライズが必要なイベント・フィルタは、POFシリアライズを使用できます。ただし、POFにはキャッシュ・プロバイダ実装間の移植性はありません。

イベント・リスナーおよびフィルタの登録

キャッシュ・エントリ・リスナーおよびイベント・フィルタは、キャッシュの構成時に静的に登録することも、キャッシュ・インスタンスが作成された後に動的に登録することもできます。どちらの方法でもリスナー構成を使用する必要があります。この構成は、CacheEntryListenerConfigurationインタフェースで定義されています。MutableCacheEntryListenerConfigurationクラスは、この項で説明される必要に応じて使用できるデフォルトの実装を提供しています。この構成は、使用するリスナー実装クラス、使用するフィルタ実装クラス、古い値をイベントの一部として送信するかどうか、イベント通知が同期的な非同期的かを指定するために使用されます。リスナーに通知が行われる順番は保証されていません。

この項には次のトピックが含まれます:

キャッシュ構成時のイベント・リスナーおよびフィルタの登録

CacheEntryListenerおよびCacheEntryEventFilterの実装を構成時に静的に登録するには、addCacheEntryListenerConfigurationメソッドを使用し、実装クラスを含め、必要に応じてリスナーを構成します。次の例では、例36-1および例36-2で作成したイベント・リスナーおよびフィルタをそれぞれ登録しています。

CachingProvider cachingProvider = Caching.getCachingProvider();
CacheManager cacheManager = cachingProvider.getCacheManager();

m_listener = new MyCacheEntryListener();

MutableConfiguration<String, String> config = 
   new MutableConfiguration<String, String>();
config.setTypes(String.class, String.class).addCacheEntryListenerConfiguration(
      new MutableCacheEntryListenerConfiguration<String, String>
      (FactoryBuilder.factoryOf(m_listener),FactoryBuilder.factoryOf(
      new MyCacheEntryEventFilter<String, String>()),true,true));

Cache<String, String> cache = cacheManager.createCache("MyCache", config);

構成例では、2つのtrueプロパティで示されるように、エントリの古い値を含め、同期ディスパッチを使用するようにイベント通知を設定しています。

removeCacheEntryListenerConfigurationメソッドは、以前に登録されたキャッシュ・エントリ・リスナーを削除します。

実行時のイベント・リスナーおよびフィルタの登録

CacheEntryListenerおよびCacheEntryEventFilterの実装をキャッシュ・インスタンスに実行時に動的に登録するには、RegisterCacheEntryListenerメソッドを使用し、実装クラスを含め、必要に応じてリスナーを構成します。次の例では、例36-1および例36-2で作成したイベント・リスナーおよびフィルタをそれぞれ登録しています。

CachingProvider cachingProvider = Caching.getCachingProvider();
CacheManager cacheManager = cachingProvider.getCacheManager();

m_listener = new MyCacheEntryListener();

MutableConfiguration<String, String> config = 
   new MutableConfiguration<String, String>();
config.setTypes(String.class, String.class);

Cache<String, String> cache = cacheManager.createCache("MyCache", config);

cache.registerCacheEntryListener(
   new MutableCacheEntryListenerConfiguration<String, String>
   (FactoryBuilder.factoryOf(m_listener),FactoryBuilder.factoryOf(
   new MyCacheEntryEventFilter<String, String>()),false,false));

構成例では、2つのfalseプロパティで示されるように、エントリの古い値を含めず、非同期ディスパッチを使用するようにイベント通知を設定しています。

deregisterCacheEntryListenerメソッドは、以前に登録されたキャッシュ・エントリ・リスナーを削除します。