Spring Cacheable与CachePut?

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

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

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

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

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

我的理解是否正确?

是。

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

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

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

@Cacheable将仅针对给定的cachekey执行一次,后续请求将不执行该方法,直到缓存过期或刷新为止。