Spring 强制@Cacheable 使用putifAbsent 而不是put
Spring force @Cacheable to use putifAbsent instead of put
我Spring缓存实现如下
@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 方法来缓存 update/put 中的值。我怎样才能强制 spring 使用 putifabsent 方法被调用,这样我可以在缓存丢失时获得 null 值,或者在其他地方第一次请求具有唯一用户名和密码的方法应该 return null随后对该用户名和密码的请求应该 return username.
嗯,查看 Spring 的缓存抽象源,似乎没有配置设置(开关)来默认 @CachePut 使用 "atomic" putIfAbsent 操作。
您可以使用 unless(或 condition)属性来模拟 "putIfAbsent" @CachePut 注释,类似于(基于 Guava impl)...
@CachePut(value="Users", key="#user.name" unless="#root.caches[0].getIfPresent(#user.name) != null")
public User save(User user){
return userRepo.save(user);
}
另请注意,我没有测试此表达式,它不会 "atomic" 或使用不同的 Cache impl 可移植。表达式 ("#root.caches[0].get(#user.name) != null") 可能更便携。
放弃 "atomic" 属性 可能并不可取,因此您还可以将 (Guava)CacheManager 扩展为 return 一个 "custom" 缓存(基于 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);
}
}
有关详细信息,请参阅 GuavaCache class。
然后...
class CustomGuavaCacheManager extends GuavaCacheManager {
@Override
protected Cache createGuavaCache(String name) {
return new CustomGuavaCache(name, createNativeGuavaCache(name), isAllowNullValues());
}
}
见GuavaCacheManager for further details, and specifically, have a look at line 93 and createGuavaCache(String name)。
希望这对您有所帮助,或者至少能给您一些更多的想法。
我Spring缓存实现如下
@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 方法来缓存 update/put 中的值。我怎样才能强制 spring 使用 putifabsent 方法被调用,这样我可以在缓存丢失时获得 null 值,或者在其他地方第一次请求具有唯一用户名和密码的方法应该 return null随后对该用户名和密码的请求应该 return username.
嗯,查看 Spring 的缓存抽象源,似乎没有配置设置(开关)来默认 @CachePut 使用 "atomic" putIfAbsent 操作。
您可以使用 unless(或 condition)属性来模拟 "putIfAbsent" @CachePut 注释,类似于(基于 Guava impl)...
@CachePut(value="Users", key="#user.name" unless="#root.caches[0].getIfPresent(#user.name) != null")
public User save(User user){
return userRepo.save(user);
}
另请注意,我没有测试此表达式,它不会 "atomic" 或使用不同的 Cache impl 可移植。表达式 ("#root.caches[0].get(#user.name) != null") 可能更便携。
放弃 "atomic" 属性 可能并不可取,因此您还可以将 (Guava)CacheManager 扩展为 return 一个 "custom" 缓存(基于 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);
}
}
有关详细信息,请参阅 GuavaCache class。
然后...
class CustomGuavaCacheManager extends GuavaCacheManager {
@Override
protected Cache createGuavaCache(String name) {
return new CustomGuavaCache(name, createNativeGuavaCache(name), isAllowNullValues());
}
}
见GuavaCacheManager for further details, and specifically, have a look at line 93 and createGuavaCache(String name)。
希望这对您有所帮助,或者至少能给您一些更多的想法。