キャッシュストレージの構成

キャッシュ抽象化は、いくつかのストレージ統合オプションを提供します。使用するには、適切な CacheManager (Cache インスタンスを制御および管理し、これらをストレージに取得するために使用できるエンティティ)を宣言する必要があります。

JDK ConcurrentMap ベースのキャッシュ

JDK ベースの Cache 実装は、org.springframework.cache.concurrent パッケージにあります。ConcurrentHashMap をバッキング Cache ストアとして使用できます。次の例は、2 つのキャッシュを構成する方法を示しています。

  • Java

  • Kotlin

  • XML

@Bean
ConcurrentMapCacheFactoryBean defaultCache() {
	ConcurrentMapCacheFactoryBean cache = new ConcurrentMapCacheFactoryBean();
	cache.setName("default");
	return cache;
}

@Bean
ConcurrentMapCacheFactoryBean booksCache() {
	ConcurrentMapCacheFactoryBean cache = new ConcurrentMapCacheFactoryBean();
	cache.setName("books");
	return cache;
}

@Bean
CacheManager cacheManager(ConcurrentMapCache defaultCache, ConcurrentMapCache booksCache) {

	SimpleCacheManager cacheManager = new SimpleCacheManager();
	cacheManager.setCaches(Set.of(defaultCache, booksCache));
	return cacheManager;
}
@Bean
fun defaultCache(): ConcurrentMapCacheFactoryBean {
	return ConcurrentMapCacheFactoryBean().apply {
		setName("default")
	}
}

@Bean
fun booksCache(): ConcurrentMapCacheFactoryBean {
	return ConcurrentMapCacheFactoryBean().apply {
		setName("books")
	}
}

@Bean
fun cacheManager(defaultCache: ConcurrentMapCache, booksCache: ConcurrentMapCache): CacheManager {
	return SimpleCacheManager().apply {
		setCaches(setOf(defaultCache, booksCache))
	}
}
<!-- simple cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
	<property name="caches">
		<set>
			<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="default"/>
			<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="books"/>
		</set>
	</property>
</bean>

上記のスニペットは、SimpleCacheManager を使用して、default および books という名前の 2 つのネストされた ConcurrentMapCache インスタンスの CacheManager を作成します。名前は各キャッシュに直接設定されることに注意してください。

キャッシュはアプリケーションによって作成されるため、そのライフサイクルにバインドされているため、基本的なユースケース、テスト、単純なアプリケーションに適しています。キャッシュは適切に拡張され、非常に高速ですが、管理、永続化機能、エビクション契約は提供されません。

ehcache ベースのキャッシュ

Ehcache 3.x は JSR-107 に完全に準拠しており、専用のサポートは必要ありません。詳細については、JSR-107 キャッシュを参照してください。

Caffeine キャッシュ

Caffeine は Guava のキャッシュを Java 8 で書き換えたもので、その実装は org.springframework.cache.caffeine パッケージにあり、Caffeine のいくつかの機能へのアクセスを提供します。

次の例では、オンデマンドでキャッシュを作成する CacheManager を構成します。

  • Java

  • Kotlin

  • XML

@Bean
CacheManager cacheManager() {
	return new CaffeineCacheManager();
}
@Bean
fun cacheManager(): CacheManager {
	return CaffeineCacheManager()
}
<bean id="cacheManager" class="org.springframework.cache.caffeine.CaffeineCacheManager"/>

明示的に使用するキャッシュを提供することもできます。その場合、マネージャーのみが利用可能になります。次の例は、その方法を示しています。

  • Java

  • Kotlin

  • XML

@Bean
CacheManager cacheManager() {
	CaffeineCacheManager cacheManager = new CaffeineCacheManager();
	cacheManager.setCacheNames(List.of("default", "books"));
	return cacheManager;
}
@Bean
fun cacheManager(): CacheManager {
	return CaffeineCacheManager().apply {
		cacheNames = listOf("default", "books")
	}
}
<bean id="cacheManager" class="org.springframework.cache.caffeine.CaffeineCacheManager">
	<property name="cacheNames">
		<set>
			<value>default</value>
			<value>books</value>
		</set>
	</property>
</bean>

Caffeine CacheManager は、カスタム Caffeine および CacheLoader もサポートしています。それらの詳細については、Caffeine ドキュメント [GitHub] (英語) を参照してください。

GemFire ベースのキャッシュ

GemFire は、メモリ指向、ディスクバックアップ、弾性スケーラブル、継続的に利用可能、アクティブ(組み込みのパターンベースのサブスクリプション通知を使用)、グローバルに複製されたデータベースであり、完全な機能を備えたエッジキャッシングを提供します。GemFire を CacheManager (およびそれ以上)として使用する方法の詳細については、Spring Data GemFire リファレンスドキュメントを参照してください。

JSR-107 キャッシュ

Spring のキャッシュ抽象化では、JSR-107 準拠のキャッシュも使用できます。JCache 実装は org.springframework.cache.jcache パッケージにあります。

繰り返しますが、これを使用するには、適切な CacheManager を宣言する必要があります。次の例は、その方法を示しています。

  • Java

  • Kotlin

  • XML

@Bean
javax.cache.CacheManager jCacheManager() {
	CachingProvider cachingProvider = Caching.getCachingProvider();
	return cachingProvider.getCacheManager();
}

@Bean
org.springframework.cache.CacheManager cacheManager(javax.cache.CacheManager jCacheManager) {
	return new JCacheCacheManager(jCacheManager);
}
@Bean
fun jCacheManager(): javax.cache.CacheManager {
	val cachingProvider = Caching.getCachingProvider()
	return cachingProvider.getCacheManager()
}

@Bean
fun cacheManager(jCacheManager: javax.cache.CacheManager): org.springframework.cache.CacheManager {
	return JCacheCacheManager(jCacheManager)
}
<bean id="cacheManager"
	  class="org.springframework.cache.jcache.JCacheCacheManager"
	  p:cache-manager-ref="jCacheManager"/>

<!-- JSR-107 cache manager setup  -->
<bean id="jCacheManager" .../>

バッキングストアなしでキャッシュを処理する

場合によっては、環境を切り替えたりテストを行ったりするときに、実際のバッキングキャッシュを構成せずにキャッシュ宣言を行うことがあります。これは無効な構成であるため、キャッシュインフラストラクチャが適切なストアを見つけることができないため、実行時に例外がスローされます。このような状況では、キャッシュ宣言を削除するのは(退屈な作業になる可能性があります)、キャッシュを実行しない単純なダミーキャッシュを接続できます。つまり、キャッシュされたメソッドが毎回呼び出されるようになります。次の例は、その方法を示しています。

  • Java

  • Kotlin

  • XML

@Bean
CacheManager cacheManager(CacheManager jdkCache, CacheManager gemfireCache) {
	CompositeCacheManager cacheManager = new CompositeCacheManager();
	cacheManager.setCacheManagers(List.of(jdkCache, gemfireCache));
	cacheManager.setFallbackToNoOpCache(true);
	return cacheManager;
}
@Bean
fun cacheManager(jdkCache: CacheManager, gemfireCache: CacheManager): CacheManager {
	return CompositeCacheManager().apply {
		setCacheManagers(listOf(jdkCache, gemfireCache))
		setFallbackToNoOpCache(true)
	}
}
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
	<property name="cacheManagers">
		<list>
			<ref bean="jdkCache"/>
			<ref bean="gemfireCache"/>
		</list>
	</property>
	<property name="fallbackToNoOpCache" value="true"/>
</bean>

前述のチェーン複数の CacheManager インスタンスの CompositeCacheManager は、fallbackToNoOpCache フラグを介して、構成されたキャッシュマネージャーで処理されないすべての定義に対して何もしないキャッシュを追加します。つまり、jdkCache または gemfireCache のいずれにも見つからないすべてのキャッシュ定義(例の前半で構成)は、情報を格納しない no-op キャッシュによって処理され、ターゲットメソッドが毎回呼び出されます。