JCacheの紹介

JCacheの概要

1. 概要

簡単に言えば、JCacheはJavaの標準キャッシュAPIです。 このチュートリアルでは、JCacheとは何か、およびJCacheをどのように使用できるかを確認します。

2. Mavenの依存関係

JCacheを使用するには、pom.xmlに次の依存関係を追加する必要があります。


    javax.cache
    cache-api
    1.0.0-PFD

ライブラリの最新バージョンはMaven Central Repositoryにあることに注意してください。

また、APIの実装をpom.xmlに追加する必要があります。ここではHazelcastを使用します。


    com.hazelcast
    hazelcast
    3.9-EA

また、Hazelcastの最新バージョンはMaven Central Repositoryにあります。

3. JCacheの実装

JCacheは、さまざまなキャッシングソリューションによって実装されます。

  • JCacheリファレンス実装

  • ハシバミ

  • Oracle Coherence

  • テラコッタエーキャッシュ

  • インフィニスパン

他のリファレンス実装とは異なり、it’s not recommended to use JCache Reference Implementation in production since it causes some concurrency issues.

4. メインコンポーネント

4.1. Cache

Cacheインターフェースには、以下の便利なメソッドがあります。

  • get() –要素のキーをパラメーターとして受け取り、要素の値を返します。キーがCacheに存在しない場合は、nullを返します。

  • getAll()Set; theメソッドが指定されたキーと関連する値をMapとして返すため、複数のキーをこのメソッドに渡すことができます

  • getAndRemove() –メソッドはそのキーを使用して値を取得し、Cacheから要素を削除します

  • put()Cacheに新しいアイテムを挿入します

  • clear()Cache内のすべての要素を削除します

  • containsKey()Cacheに特定のキーが含まれているかどうかを確認します

ご覧のとおり、メソッドの名前はほとんど一目瞭然です。 これらのメソッドおよびその他のメソッドの詳細については、Javadocにアクセスしてください。

4.2. CacheManager

CacheManagerは、APIの最も重要なインターフェースの1つです。 これにより、Cachesを確立、構成、および閉じることができます。

4.3. CachingProvider

CachingProviderは、CacheManagersのライフサイクルを作成および管理できるようにするインターフェイスです。

4.4. Configuration

Configurationは、Cachesを構成できるようにするインターフェースです。 1つの具体的な実装–MutableConfigurationとサブインターフェイス–CompleteConfigurationがあります。

5. Cacheの作成

単純なCacheを作成する方法を見てみましょう。

CachingProvider cachingProvider = Caching.getCachingProvider();
CacheManager cacheManager = cachingProvider.getCacheManager();
MutableConfiguration config
  = new MutableConfiguration<>();
Cache cache = cacheManager
  .createCache("simpleCache", config);
cache.put("key1", "value1");
cache.put("key2", "value2");
cacheManager.close();

私たちがしているのは:

  • CacheManagerオブジェクトの作成に使用しているCachingProviderオブジェクトの作成

  • Configurationインターフェースの実装であるMutableConfigurationオブジェクトの作成

  • 以前に作成したCacheManagerオブジェクトを使用してCacheオブジェクトを作成する

  • すべてのエントリを入れて、Cacheオブジェクトにキャッシュする必要があります

  • CacheManagerを閉じて、Cacheによって使用されているリソースを解放します

pom.xmlにJCacheの実装を提供しない場合、次の例外がスローされます。

javax.cache.CacheException: No CachingProviders have been configured

これは、JVMがgetCacheManager()メソッドの具体的な実装を見つけることができなかったためです。

6. EntryProcessor

EntryProcessorを使用すると、Cacheに再度追加しなくても、アトミック操作を使用してCacheエントリを変更できます。 これを使用するには、EntryProcessorインターフェースを実装する必要があります。

public class SimpleEntryProcessor
  implements EntryProcessor, Serializable {

    public String process(MutableEntry entry, Object... args)
      throws EntryProcessorException {

        if (entry.exists()) {
            String current = entry.getValue();
            entry.setValue(current + " - modified");
            return current;
        }
        return null;
    }
}

それでは、EntryProcessorの実装を使用しましょう。

@Test
public void whenModifyValue_thenCorrect() {
    this.cache.invoke("key", new SimpleEntryProcessor());

    assertEquals("value - modified", cache.get("key"));
}

7. イベントリスナー

EventType列挙型で定義されているイベントタイプのいずれかをトリガーすると、Event Listeners allow us to take actionsは次のようになります。

  • 作成した

  • 更新しました

  • 削除済み

  • 期限切れ

まず、使用するイベントのインターフェースを実装する必要があります。

たとえば、CREATEDおよびUPDATEDイベントタイプを使用する場合は、インターフェイスCacheEntryCreatedListenerおよびCacheEntryUpdatedListenerを実装する必要があります。

例を見てみましょう:

public class SimpleCacheEntryListener implements
  CacheEntryCreatedListener,
  CacheEntryUpdatedListener,
  Serializable {

    private boolean updated;
    private boolean created;

    // standard getters

    public void onUpdated(
      Iterable> events) throws CacheEntryListenerException {
        this.updated = true;
    }

    public void onCreated(
      Iterable> events) throws CacheEntryListenerException {
        this.created = true;
    }
}

それでは、テストを実行しましょう。

@Test
public void whenRunEvent_thenCorrect() throws InterruptedException {
    this.listenerConfiguration
      = new MutableCacheEntryListenerConfiguration(
        FactoryBuilder.factoryOf(this.listener), null, false, true);
    this.cache.registerCacheEntryListener(this.listenerConfiguration);

    assertEquals(false, this.listener.getCreated());

    this.cache.put("key", "value");

    assertEquals(true, this.listener.getCreated());
    assertEquals(false, this.listener.getUpdated());

    this.cache.put("key", "newValue");

    assertEquals(true, this.listener.getUpdated());
}

8. CacheLoader

CacheLoader allowsus to use read-through modeto treat cache as the main data store and read data from it

実際のシナリオでは、キャッシュに実際のストレージからデータを読み取らせることができます。

例を見てみましょう。 まず、CacheLoaderインターフェイスを実装する必要があります。

public class SimpleCacheLoader
  implements CacheLoader {

    public String load(Integer key) throws CacheLoaderException {
        return "fromCache" + key;
    }

    public Map loadAll(Iterable keys)
      throws CacheLoaderException {
        Map data = new HashMap<>();
        for (int key : keys) {
            data.put(key, load(key));
        }
        return data;
    }
}

それでは、CacheLoaderの実装を使用しましょう。

public class CacheLoaderTest {

    private Cache cache;

    @Before
    public void setup() {
        CachingProvider cachingProvider = Caching.getCachingProvider();
        CacheManager cacheManager = cachingProvider.getCacheManager();
        MutableConfiguration config
          = new MutableConfiguration<>()
            .setReadThrough(true)
            .setCacheLoaderFactory(new FactoryBuilder.SingletonFactory<>(
              new SimpleCacheLoader()));
        this.cache = cacheManager.createCache("SimpleCache", config);
    }

    @Test
    public void whenReadingFromStorage_thenCorrect() {
        for (int i = 1; i < 4; i++) {
            String value = cache.get(i);

            assertEquals("fromCache" + i, value);
        }
    }
}

9. 結論

このチュートリアルでは、JCacheとは何かを確認し、いくつかの実用的なシナリオでその重要な機能のいくつかを調べました。

いつものように、このチュートリアルの完全な実装はover on GitHubにあります。