web-dev-qa-db-ja.com

Spring Cacheable vs CachePut?

@CachePut or @Cacheable(value = "CustomerCache", key = "#id")
public Customer updateCustomer(Customer customer) {
   sysout("i am inside updateCustomer");
    ....
    return customer;
}

以下のドキュメントをCachePutソースコードの下に見つけました

CachePutアノテーションは、ターゲットメソッドをスキップさせません。むしろ、常にメソッドを呼び出し、その結果をキャッシュに配置します。

@Cacheableを使用する場合、updateCustomerメソッドは1回だけ実行され、結果はキャッシュで更新されます。 updateCustomerへの後続の呼び出しはupdateCustomerを実行せず、キャッシュを更新するだけです。

@CachePutの場合、updateCustomerメソッドは各呼び出しで実行され、結果はキャッシュで更新されます。

私の理解は正しいですか?

20
M Sach

はい。

私も確認するテストを行いました:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CacheableTest.CacheConfigurations.class)
public class CacheableTest {

    public static class Customer {

        final private String id;
        final private String name;

        public Customer(String id, String name) {
            this.id = id;
            this.name = name;
        }

        public String getId() {
            return id;
        }

        public String getName() {
            return name;
        }

    }

    final public static AtomicInteger cacheableCalled = new AtomicInteger(0);
    final public static AtomicInteger cachePutCalled = new AtomicInteger(0);

    public static class CustomerCachedService {


        @Cacheable("CustomerCache")
        public Customer cacheable(String v) {
            cacheableCalled.incrementAndGet();
            return new Customer(v, "Cacheable " + v);
        }

        @CachePut("CustomerCache")
        public Customer cachePut(String b) {
            cachePutCalled.incrementAndGet();
            return new Customer(b, "Cache put " + b);
        }

    }

    @Configuration
    @EnableCaching()
    public static class CacheConfigurations {

        @Bean
        public CustomerCachedService customerCachedService() {
            return new CustomerCachedService();
        }

        @Bean
        public CacheManager cacheManager() {
            return new GuavaCacheManager("CustomerCache");
        }

    }

    @Autowired
    public CustomerCachedService cachedService;

    @Test
    public void testCacheable() {
        for(int i = 0; i < 1000; i++) {
            cachedService.cacheable("A");
        }
        Assert.assertEquals(cacheableCalled.get(), 1);
    }

    @Test
    public void testCachePut() {
        for(int i = 0; i < 1000; i++) {
            cachedService.cachePut("B");
        }
        Assert.assertEquals(cachePutCalled.get(), 1000);
    }

}
15
mavarazy

@CachePutは常にメソッドの実行を許可します。メソッドの実行結果でキャッシュを更新する場合に一般的に使用されます。
例:キャッシュを完全に消すのではなく、キャッシュされた古いデータを更新する場合。

@Cacheableは、指定されたキャッシュキーに対して1回だけ実行され、キャッシュが期限切れになるかフラッシュされるまで、後続のリクエストはメソッドを実行しません。

13
minion

はい、あなたは絶対に正しいです。

@Cacheputと@Cacheableは組み合わせて使用​​されます。

@Cacheableは、呼び出しごとにキャッシュを更新しません。古いデータを削除するには、古いデータをクリアする@Cacheputを使用するサービスが必要です。

以下の回答は、グアバキャッシングを使用してキャッシュを構築している人向けです。グアバキャッシングを使用すると、@ Cacheputの場合とは異なる一定の期間が経過すると、適用される時間間隔によってキャッシュが空になります。 @Cacheputは、古い値のみを更新するため、キャッシュを更新するたびにメソッドを呼び出します。

私の答えがあなたの質問をクリアすることを願っています。

0
Somil Aseeja