Java Spring Cacheable vs CachePut?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28516398/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 06:22:05  来源:igfitidea点击:

Spring Cacheable vs CachePut?

javaspringcaching

提问by M Sach

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

I found below documentation under CachePutsource code

我在CachePut源代码下找到了以下文档

CachePut annotation does not cause the target method to be skipped - rather it always causes the method to be invoked and its result to be placed into the cache.

CachePut 注释不会导致目标方法被跳过——而是总是导致方法被调用并将其结果放入缓存中。

Does it mean if I use @Cacheable, updateCustomer method will be executed only once and result will be updated in cache. Subsequent calls to updateCustomer will not execute updateCustomer , it will just update the cache.

这是否意味着如果我使用@Cacheable, updateCustomer 方法将只执行一次并且结果将在缓存中更新。对 updateCustomer 的后续调用不会执行 updateCustomer ,它只会更新缓存。

While in case of @CachePut, updateCustomermethod will be executed on each call and result will be updated in cache.

而在 的情况下@CachePutupdateCustomer方法将在每次调用时执行,结果将在缓存中更新。

Is my understanding correct?

我的理解正确吗?

采纳答案by mavarazy

Yes.

是的。

I even made a test to be sure:

我什至做了一个测试来确定:

@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);
    }

}

回答by minion

@CachePut always lets the method execute. It is generally used if you want your cache to be updated with the result of the method execution.
Example: When you want to update a stale data which is cached, instead of blowing the cache completely.

@CachePut 总是让方法执行。如果您希望使用方法执行的结果更新缓存,则通常使用它。
示例:当您想要更新缓存的陈旧数据时,而不是完全清除缓存。

@Cacheable will be executed only once for the given cachekey and subsequent requests won't execute the method, until the cache expires or gets flushed.

@Cacheable 只会为给定的缓存键执行一次,后续请求不会执行该方法,直到缓存过期或被刷新。

回答by Somil Aseeja

Yes, you are absolutely correct.

是的,你是完全正确的。

@Cacheput and @Cacheable are used in conjunction.

@Cacheput 和@Cacheable 结合使用。

@Cacheable will not update the cache on every call. In order to remove the stale data, there must be a service that uses the @Cacheput that clears the stale data.

@Cacheable 不会在每次调用时更新缓存。为了删除陈旧数据,必须有一个使用@Cacheput 清除陈旧数据的服务。

Below answer is for the ones who are using guava caching to build cache. Using guava caching, the time interval that is applied will empty the cache after a certain period of time which is not the case with @Cacheput. @Cacheput will only update the values that are stale and hence it calls the method every time to update the cache.

以下答案适用于使用番石榴缓存构建缓存的人。使用番石榴缓存,应用的时间间隔将在一段时间后清空缓存,而@Cacheput 并非如此。@Cacheput 只会更新过时的值,因此它每次都会调用该方法来更新缓存。

I hope my answer clears your question.

我希望我的回答能解决你的问题。