Spring Cacheable与CachePut?

M S*_*ach 22 java spring caching

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

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

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

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

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

我的理解是否正确?

mav*_*azy 15

是.

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

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

}
Run Code Online (Sandbox Code Playgroud)


min*_*ion 14

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

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

  • 因此,如果我使用`@CacheEvict` 批注触发方法,那么在使用`@Cachable` 批注的方法之后将被执行? (2认同)
  • 如果每次都运行该方法,使用 @CachePut 缓存数据有什么好处吗? (2认同)