Spring force@Cacheable可以使用putifAbsent而不是put

Spring force@Cacheable可以使用putifAbsent而不是put,spring,guava,spring-cache,Spring,Guava,Spring Cache,我已经实现了SpringCache,如下所示 @Component public class KPCacheExample { private static final Logger LOG = LoggerFactory.getLogger(KPCacheExample.class); @CachePut(value="kpCache") public String saveCache(String userName, String password){

我已经实现了SpringCache,如下所示

@Component
public class KPCacheExample {

    private static final Logger LOG = LoggerFactory.getLogger(KPCacheExample.class);

    @CachePut(value="kpCache")
    public String saveCache(String userName, String password){
        LOG.info("Called saveCache");
        return userName;
    }

    @Cacheable(value="kpCache")
    public String getCache(String userName, String password){
        LOG.info("Called getCache");
        return "kp";
    }

}
和Java配置文件

@Configuration
@ComponentScan(basePackages={"com.kp"})
public class GuavaCacheConfiguration {


    @Bean
    public CacheManager cacheManager() {
     GuavaCacheManager guavaCacheManager =  new GuavaCacheManager("kpCache");
     guavaCacheManager.setCacheBuilder(CacheBuilder.newBuilder().expireAfterAccess(2000, TimeUnit.MILLISECONDS).removalListener(new KPRemovalListener()));
     return guavaCacheManager;
    }

}

默认情况下,spring在缓存接口中使用put方法来更新/放置缓存中的值。如何强制spring使用putifabsent方法进行调用,这样,如果缓存丢失,或者在其他情况下,对具有唯一用户名和密码的方法的第一个请求应返回null,对该用户名和密码的后续请求应返回username。

,查看Spring的缓存抽象源,似乎没有一个配置设置(开关)来默认@CachePut以使用“原子”putIfAbsent操作

您可以使用@CachePut注释的除非(或条件)属性来模拟“putIfAbsent”,类似于(基于Guava impl)

还要注意的是,我没有测试这个表达式,它不会是“原子的”,也不会使用不同的缓存impl进行移植。表达式(“#root.caches[0].get(#user.name)!=null”)可能更便于移植

放弃“原子”属性可能并不可取,因此您还可以扩展(Guava)CacheManager以返回一个“自定义”缓存(基于GuavaCache),该缓存覆盖put操作以委托给“putIfAbsent”

class CustomGuavaCache extends GuavaCache {

    CustomGuavaCache(String name, com.google.common.cache.Cache<Object, Object> cache, boolean allowNullValues) {
        super(name, cache, allowNullValues);
    }

    @Override
    public void put(Object key, Object value) {
        putIfAbsent(key, value);
    }
}
有关更多详细信息,请参阅,具体来说,请查看和

希望这对你有所帮助,或者至少能给你更多的想法

class CustomGuavaCache extends GuavaCache {

    CustomGuavaCache(String name, com.google.common.cache.Cache<Object, Object> cache, boolean allowNullValues) {
        super(name, cache, allowNullValues);
    }

    @Override
    public void put(Object key, Object value) {
        putIfAbsent(key, value);
    }
}
class CustomGuavaCacheManager extends GuavaCacheManager {

    @Override
    protected Cache createGuavaCache(String name) {
        return new CustomGuavaCache(name, createNativeGuavaCache(name), isAllowNullValues());
    }
}