Spring 可缓存与 CachePut?
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 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.
这是否意味着如果我使用 @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 执行一次,后续请求不会执行该方法,直到缓存过期或被刷新。
是的,你完全正确。
@Cacheput和@Cacheable配合使用
@Cacheable 不会在每次调用时更新缓存。为了删除陈旧数据,必须有一个使用清除陈旧数据的@Cacheput 的服务。
以下答案适用于使用番石榴缓存来构建缓存的人。
使用番石榴缓存,应用的时间间隔将在一段时间后清空缓存,而@Cacheput 则不是这种情况。 @Cacheput 只会更新陈旧的值,因此它每次都会调用该方法来更新缓存。
希望我的回答能解决您的问题。
@CachePut or @Cacheable(value = "CustomerCache", key = "#id")
public Customer updateCustomer(Customer customer) {
sysout("i am inside updateCustomer");
....
return customer;
}
我在 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.
这是否意味着如果我使用 @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 执行一次,后续请求不会执行该方法,直到缓存过期或被刷新。
是的,你完全正确。
@Cacheput和@Cacheable配合使用
@Cacheable 不会在每次调用时更新缓存。为了删除陈旧数据,必须有一个使用清除陈旧数据的@Cacheput 的服务。
以下答案适用于使用番石榴缓存来构建缓存的人。 使用番石榴缓存,应用的时间间隔将在一段时间后清空缓存,而@Cacheput 则不是这种情况。 @Cacheput 只会更新陈旧的值,因此它每次都会调用该方法来更新缓存。
希望我的回答能解决您的问题。