JCacheの紹介

1概要

簡単に言えば、http://www.javadoc.io/doc/javax.cache/cache-api/1.0.0[JCache]はJavaの標準キャッシングAPIです。このチュートリアルでは、JCacheとは何か、またその使い方について説明します。

2 Mavenの依存関係

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

<dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
    <version>1.0.0-PFD</version>
</dependency>

このライブラリの最新版はhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22cache-api%22[Maven Central Repository]にあります。

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

<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast</artifactId>
    <version>3.9-EA</version>
</dependency>

Hazelcastの最新版はhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22hazelcast%22[Maven Central Repository]にもあります。

3 JCacheの実装

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

  • JCacheリファレンス実装

  • ヘーゼルキャスト

  • Oracle Coherence

  • Terracotta Ehcache

  • Infinispan

他のリファレンス実装とは異なり、** 同時実行の問題が発生するため、本番環境でJCacheリファレンス実装を使用することはお勧めできません。

4メインコンポーネント

4.1. キャッシュ

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

  • get() - 要素のキーをパラメータとして受け取り、

要素の値キーが存在しない場合は null を返します。 キャッシュ ** getAll() - このメソッドには____Setとして複数のキーを渡すことができます。

t _heメソッドは、指定されたキーと関連付けられた値を Map として返します。 ** getAndRemove()_ - メソッドはそのキーを使用して値を取得し、

Cache から要素を削除します ** put() - Cache に新しい項目を挿入します

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

  • containsKey() - Cache に特定のキーが含まれているかどうかを調べる

ご覧のとおり、メソッドの名前は一目瞭然です。これらの方法やその他の方法の詳細については、http://www.javadoc.io/doc/javax.cache/cache-api/1.0.0[Javadoc]を参照してください。

4.2. CacheManager

CacheManager は、APIの最も重要なインタフェースの1つです。これにより、 キャッシュ を確立、設定、および閉じることができます。

4.3. CachingProvider

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

4.4. 設定

Configuration は、 Caches を設定するためのインタフェースです。

具体的な実装は MutableConfiguration とサブインターフェース CompleteConfiguration です。

5 Cache を作成する

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

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

私たちがしているのは、

  • CachingProvider オブジェクトを作成します。これを作成するために使用しています。

CacheManager オブジェクト ** 実装である MutableConfiguration オブジェクトを作成する

Configuration インターフェースの概要 ** 作成した CacheManager オブジェクトを使用して Cache オブジェクトを作成する

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

  • によって使用されたリソースを解放するために CacheManager を閉じる

キャッシュ

  • pom.xml でJCacheの実装を提供していない場合は、次の例外が発生します。

javax.cache.CacheException: No CachingProviders have been configured

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

6. EntryProcessor

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

public class SimpleEntryProcessor
  implements EntryProcessor<String, String, String>, Serializable {

    public String process(MutableEntry<String, String> 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. イベントリスナー

  • Event Listenersは EventType enumで定義されたイベントタイプのどれかをトリガーしたときにアクションを起こすことを可能にします。

  • 作成した

  • 更新しました

  • 削除済み

  • EXPIRED

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

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

例を見てみましょう。

public class SimpleCacheEntryListener implements
  CacheEntryCreatedListener<String, String>,
  CacheEntryUpdatedListener<String, String>,
  Serializable {

    private boolean updated;
    private boolean created;

   //standard getters

    public void onUpdated(
      Iterable<CacheEntryEvent<? extends String,
      ? extends String>> events) throws CacheEntryListenerException {
        this.updated = true;
    }

    public void onCreated(
      Iterable<CacheEntryEvent<? extends String,
      ? extends String>> events) throws CacheEntryListenerException {
        this.created = true;
    }
}

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

@Test
public void whenRunEvent__thenCorrect() throws InterruptedException {
    this.listenerConfiguration
      = new MutableCacheEntryListenerConfiguration<String, String>(
        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 を使用すると、 スルースルーモードを使用してキャッシュをメインデータストアとして扱い、そこからデータを読み取ることができます** 。

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

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

public class SimpleCacheLoader
  implements CacheLoader<Integer, String> {

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

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

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

public class CacheLoaderTest {

    private Cache<Integer, String> cache;

    @Before
    public void setup() {
        CachingProvider cachingProvider = Caching.getCachingProvider();
        CacheManager cacheManager = cachingProvider.getCacheManager();
        MutableConfiguration<Integer, String> 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とは何かを見て、いくつかの実用的なシナリオでその重要な機能のいくつかを調べました。

いつものように、このチュートリアルの完全な実装はhttps://github.com/eugenp/tutorials/tree/master/libraries-data[over on GitHub]にあります。