Java Spring可缓存vs CachePut?

Java Spring可缓存vs CachePut?,java,spring,caching,Java,Spring,Caching,我在CachePut源代码下找到了以下文档 CachePut注释不会导致跳过目标方法- 相反,它总是导致方法被调用,其结果是 放入缓存中 这是否意味着如果我使用@Cacheable,updateCustomer方法将只执行一次,结果将在缓存中更新。随后致电 updateCustomer不会执行updateCustomer,它只会更新缓存 而在@CachePut的情况下,每次调用都将执行updateCustomer方法,结果将在缓存中更新 我的理解正确吗?是的 我甚至做了一个测试来确定: @Cac

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

CachePut注释不会导致跳过目标方法- 相反,它总是导致方法被调用,其结果是 放入缓存中

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

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

我的理解正确吗?

是的

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

@CachePut or @Cacheable(value = "CustomerCache", key = "#id")
public Customer updateCustomer(Customer customer) {
   sysout("i am inside updateCustomer");
    ....
    return customer;
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CacheableTest.CacheConfigurations.class)
公共类可缓存测试{
公共静态类客户{
最终私有字符串id;
最后一个私有字符串名;
公共客户(字符串id、字符串名称){
this.id=id;
this.name=名称;
}
公共字符串getId(){
返回id;
}
公共字符串getName(){
返回名称;
}
}
final public static AtomicInteger cacheableCalled=新的AtomicInteger(0);
最终公共静态AtomicInteger cachePutCalled=新的AtomicInteger(0);
公共静态类CustomerCachedService{
@可缓存(“CustomerCache”)
公共客户可缓存(字符串v){
cacheableCalled.incrementAndGet();
返回新客户(v,“可缓存”+v);
}
@CachePut(“CustomerCache”)
公共客户缓存输出(字符串b){
cachePutCalled.incrementAndGet();
返回新客户(b,“缓存放置”+b);
}
}
@配置
@EnableCaching()
公共静态类缓存配置{
@豆子
公共CustomerCachedService CustomerCachedService(){
返回新的CustomerCachedService();
}
@豆子
公共缓存管理器缓存管理器(){
返回新的GuavaCacheManager(“CustomerCache”);
}
}
@自动连线
公共客户缓存服务缓存服务;
@试验
public void testCacheable(){
对于(int i=0;i<1000;i++){
缓存服务。可缓存(“A”);
}
Assert.assertEquals(cacheableCalled.get(),1);
}
@试验
公共void testCachePut(){
对于(int i=0;i<1000;i++){
cachedService.cachePut(“B”);
}
Assert.assertEquals(cachePutCalled.get(),1000);
}
}

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


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

是的,您完全正确

@Cacheput和@Cacheable结合使用

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

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


我希望我的回答能澄清你的问题。

因此,如果我使用
@cacheexecute
注释触发方法,那么在使用
@Cachable
注释的方法之后将执行?@KamilW.-是的,它应该执行。如果每次都运行该方法,那么使用@CachePut缓存数据有什么好处吗?@Grez.Kev,如果您想清理缓存,可以使用
@CachePut
,例如,一个陈旧的数据放在那里,您想重新缓存一些后端数据。我们不能同时使用“@Cacheable”和“@CachePut”。您可以检入弹簧参考:
@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);
    }

}