春のキャッシングガイド

春のキャッシングガイド

1. キャッシュの抽象化?

この記事では、use the Caching Abstraction in Springを実行する方法を示します。一般的に、システムのパフォーマンスを向上させます。

いくつかの実際のメソッドの例で単純なキャッシュを有効にし、スマートキャッシュ管理を通じてこれらの呼び出しのパフォーマンスを実際に改善する方法について説明します。

参考文献:

Spring Boot Ehcacheの例

EhcacheでSpringを使用するための迅速かつ実用的なガイド。

Spring Bootのキャッシュエビクション

Spring Bootでキャッシュを無効にする方法を学びます。

2. 入門

Springが提供するコアキャッシングの抽象化は、spring-context moduleにあります。 したがって、Mavenを使用する場合、pom.xmlには次の依存関係が含まれている必要があります。


    org.springframework
    spring-context
    5.1.8.RELEASE

興味深いことに、spring-context モジュールの上にあるspring-context-support,という名前の別のモジュールがあり、EhCacheCaffeineなどに支えられたさらにいくつかのCacheManagers を提供します。 これらをキャッシュストレージとして使用する場合は、代わりにspring-context-support moduleを使用してください。


    org.springframework
    spring-context-support
    5.1.8.RELEASE

spring-context-supportモジュールは推移的にspring-context モジュールに依存するため、spring-context.に対して個別の依存関係宣言を行う必要はありません。

2.1. 春のブーツ

Spring Bootユーザーの場合は、spring-boot-starter-cache starterパッケージを使用して、キャッシュの依存関係を簡単に追加します。


    org.springframework.boot
    spring-boot-starter-cache

内部では、スターターがspring-context-support moduleをもたらします。

3. キャッシュを有効にする

キャッシングを有効にするために、Springはフレームワークの他の設定レベル機能を有効にするのと同じように、アノテーションを有効に使用します。

キャッシュ機能は、@EnableCachingアノテーションを任意の構成クラスに追加するだけで宣言的に有効にできます。

@Configuration
@EnableCaching
public class CachingConfig {

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("addresses");
    }
}

もちろん、enable cache management with XMLの構成も可能です。


    

    
        
            
                
            
        
    

Note:キャッシュを有効にした後、最小限のセットアップで、mustcacheManagerを登録します。

キャッシュを構成するためのUsing XML does enable more flexible options –独自のCache-Manager、Cache-Resolver、Error-Handlerを指定でき、通常、より高度なカスタマイズオプションを使用できます(詳細についてはrefer to the Javadoc)。

3.1. 春のブーツ

Spring Bootを使用する場合、EnableCaching annotationと一緒にクラスパスにスターターパッケージが存在するだけで同じConcurrentMapCacheManager. が登録されるため、個別のBean宣言は必要ありません。

また、1つ以上のCacheManagerCustomizer<T> beansを使用してauto-configuredCacheManager をカスタマイズできます。

@Component
public class SimpleCacheCustomizer
  implements CacheManagerCustomizer {

    @Override
    public void customize(ConcurrentMapCacheManager cacheManager) {
        cacheManager.setCacheNames(asList("users", "transactions"));
    }
}

CacheAutoConfiguration auto-configurationはこれらのカスタマイザーを取得し、完全に初期化する前に現在のCacheManager に適用します。

4. アノテーション付きのキャッシングを使用する

キャッシングを有効にしたら、次のステップは、キャッシング動作を宣言アノテーションを使用してメソッドにバインドすることです。

4.1. @Cacheable

メソッドのキャッシュ動作を有効にする最も簡単な方法は、メソッドを@Cacheableで区切り、結果が格納されるキャッシュの名前でパラメーター化することです。

@Cacheable("addresses")
public String getAddress(Customer customer) {...}

getAddress()呼び出しは、実際にメソッドを呼び出してから結果をキャッシュする前に、まずキャッシュaddressesをチェックします。

ほとんどの場合、1つのキャッシュで十分ですが、Springフレームワークはパラメーターとして渡される複数のキャッシュもサポートしています。

@Cacheable({"addresses", "directory"})
public String getAddress(Customer customer) {...}

____この場合、いずれかのキャッシュに必要な結果が含まれている場合、結果が返され、メソッドは呼び出されません。

4.2. @CacheEvict __

さて、すべてのメソッドを@Cacheableにすることの問題は何でしょうか?

問題はサイズ–we don’t want to populate the cache with values that we don’t need oftenです。 キャッシュは非常に大きく、非常に速く成長する可能性があり、多くの古いデータや未使用のデータを保持することができます。

@CacheEvictアノテーションは、1つ以上/すべての値の削除を示すために使用されます。これにより、新しい値をキャッシュに再度ロードできます。

@CacheEvict(value="addresses", allEntries=true)
public String getAddress(Customer customer) {...}

ここでは、空にするキャッシュと組み合わせて追加のパラメーターallEntriesを使用しています。これにより、キャッシュaddressesのすべてのエントリがクリアされ、新しいデータに備えることができます。

__ 4.3. @CachePut

@CacheEvictは、古くて未使用のエントリを削除することで、大きなキャッシュ内のエントリを検索するオーバーヘッドを削減しますが、理想的には、avoid evicting too much data out of the cacheを使用する必要があります。

代わりに、エントリが変更されるたびに、エントリを選択的かつインテリジェントに更新する必要があります。

@CachePutアノテーションを使用すると、メソッドの実行を妨げることなく、キャッシュの内容を更新できます。 つまり、メソッドは常に実行され、結果がキャッシュされます。

@CachePut(value="addresses")
public String getAddress(Customer customer) {...}

@Cacheable@CachePutの違いは、@Cacheableskip running the methodになるのに対し、@CachePutactually run the methodになり、その結果をキャッシュに入れることです。

4.4. @Caching

メソッドをキャッシュするために同じタイプの複数の注釈を使用する場合はどうなりますか。 以下の誤った例を見てください:

@CacheEvict("addresses")
@CacheEvict(value="directory", key=customer.name)
public String getAddress(Customer customer) {...}

Javaは特定のメソッドに対して同じタイプの複数のアノテーションを宣言できないため、上記のコードはコンパイルに失敗します。

上記の問題の回避策は次のとおりです。

@Caching(evict = {
  @CacheEvict("addresses"),
  @CacheEvict(value="directory", key="#customer.name") })
public String getAddress(Customer customer) {...}

上記のコードスニペットに示されているように、group multiple caching annotations@Cachingを組み合わせて使用​​し、それを使用して独自のカスタマイズされたキャッシュロジックを実装できます。

4.5. @CacheConfig

@CacheConfigアノテーションを使用すると、streamline some of the cache configuration into a single place – at the class levelを実行できます。これにより、複数回宣言する必要がなくなります。

@CacheConfig(cacheNames={"addresses"})
public class CustomerDataService {

    @Cacheable
    public String getAddress(Customer customer) {...}

5. 条件付きキャッシング

場合によっては、キャッシュがすべての状況でメソッドに対してうまく機能しないことがあります。

たとえば、@CachePutアノテーションの例を再利用すると、メソッドが実行されるだけでなく、毎回結果がキャッシュされます。

@CachePut(value="addresses")
public String getAddress(Customer customer) {...}

5.1. 条件パラメータ

ここで、注釈がアクティブになるタイミングをさらに制御したい場合は、@CachePutを、SpEL式を受け取る条件パラメーターでパラメーター化して、その式の評価に基づいて結果が確実にキャッシュされるようにすることができます。

@CachePut(value="addresses", condition="#customer.name=='Tom'")
public String getAddress(Customer customer) {...}

5.2. パラメータを除いて

unlessパラメータを介してキャッシュbased on the output of the method rather than the inputを制御することもできます。

@CachePut(value="addresses", unless="#result.length()<64")
public String getAddress(Customer customer) {...}

上記の注釈は、アドレスが64文字より短い場合を除き、アドレスをキャッシュします。

conditionおよびunlessパラメータは、すべてのキャッシュアノテーションと組み合わせて使用​​できることを知っておくことが重要です。

この種の条件付きキャッシュは、すべての操作に一般的な動作を強制する代わりに、大きな結果を管理し、入力パラメーターに基づいて動作をカスタマイズするのに非常に役立ちます。

6. 宣言的なXMLベースのキャッシュ

アプリケーションのソースコードにアクセスできない場合、またはキャッシュ動作を外部に挿入したい場合は、宣言型XMLベースのキャッシュを使用することもできます。

XML構成は次のとおりです。