Spring启动@CachePut,它是如何工作的

时间:2016-08-22 12:31:23

标签: spring spring-boot spring-data-jpa spring-cache

我试图更新spring缓存中的值,但是@CachePut不会替换实际值,而是使用相同的键放置另一个值:

Cachename:noTimeCache:

  • 键:SYSTEM_STATUS,val:ON
  • 键:SYSTEM_STATUS,val:OFF

1.为什么?

我的缓存服务:

@CachePut(value = "noTimeCache", key = "#setting.getSetting().name()")
public String updateGlobalCacheValue(GlobalSettings setting) {
    System.out.println("Setting: " + setting.getSetting().name() + ", val: " + setting.getValue());
    return setting.getValue();
}

我知道它看起来很有趣,但我需要使用jpa存储库。也许有人有更好的解决方案。

2.为什么我不能像这样使用函数参数作为@Cacheable键?

@Cacheable(value = "noTimeCache", key = "#setting.name()", unless = "#result == null")
@Query("SELECT gs.value FROM GlobalSettings gs WHERE gs.setting = ?1")
String getGlobalSettingValue(Settings setting);

它告诉我设置为空。

3.是否可以覆盖@Repositository接口方法,例如save()为它们添加注释@Cacheable?

2 个答案:

答案 0 :(得分:1)

1- @CachePut不会替换实际值,而是添加另一个值:delete key ="#setting.name"以这种方式,keygenarator将使用GlobalSettings的哈希码(验证哈希码是否正确实现),并验证缓存的名称" noTimeCache"没有指定其他方法。

2 - 如果"设置"请参阅此链接http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html参数是GlobalSettings中的一个属性 将SpEL表达式#settings.getSetting()。name()更改为#setting.setting.name

3 - 如果您使用的是Java 6,则可以执行以下操作(不知道是否可以使用java 7或8):

public interface GlobalSettingsRepository extends JpaRepository<GlobalSettings, Long>{

@Override
@CacheEvict(value = {"noTimeCache"}, allEntries = true)
GlobalSettings save(GlobalSettings globalSettings);
}

答案 1 :(得分:0)

感谢您的回答。它帮助我解决问题。

@CachePut替换值,但键中存在问题。我使用这样的东西:

@Cacheable(value = "globalSettings", unless = "#result == null")
@Query("SELECT gs.value FROM GlobalSettings gs WHERE gs.setting = ?1")
String getGlobalSettingValue(Settings setting);

设置为枚举,默认密钥为枚举名称,例如SYSTEM_STATUS。

和此:

@Cacheable(value = "globalSettings", key = "#setting.name()")
public String getGlobalSettingEnumValue(Settings setting) {
    return Settings.valueOf(setting.name()).getDefaultValue();
}

还会将密钥保存为STSYEM_STATUS。

Key是相同的,但缓存解释这就像2个不同的缓存值,我不知道为什么。

U不能像#setting那样在存储库类中使用变量名,它必须是#p0之类的参数索引,可能是因为spring数据使用了他自己的代理类。

这解决了我所有的问题,现在缓存工作正常。