当然,有多种选择,但像往常一样,春天支持你。
最简单最简单的方法是在 save 方法上利用 Spring 的 @Caching 注释,就像这样......
@Caching(evict = {
@CacheEvict(cacheNames = "Users", key="#user.name"),
@CacheEvict(cacheNames = "Users", key="#user.email")
})
User save(User user);
为了您的参考,我创建了一个示例测试类来演示此工作 here。
您会注意到我在UserRepository 上使用Spring 的 Cache Abstraction 注释模仿了您上面的示例。在这种情况下,我的 repo 由 Pivotal GemFire 支持,但任何数据存储都可以使用。我使用 ConcurrentMap 作为我的缓存提供程序,使用 Spring 的 ConcurrentMapCacheManager,但当然,任何缓存提供程序都可以。
我的test case 继续保存一个新的 User,确保用户存储在尚未缓存的状态。然后测试继续执行查询方法(findByName、findByEmail),确保在每种情况下都适当地缓存用户实体。然后,我从底层数据存储中删除该实体,并确保该实体仍处于缓存状态。最后,在关键时刻,我修改实体,重新保存实体,断言实体是由 所有 条目已从缓存中“驱逐”出来的。
作为另一种优化,您还可以尝试在这种情况下将@CachePut 注释与2 个@CacheEvict 注释结合起来,这可以根据新的更新实体恢复缓存,例如...
@Caching(
evict = {
@CacheEvict(cacheNames = "Users", key="#a0.name", beforeInvocation = true),
@CacheEvict(cacheNames = "Users", key="#a0.email", beforeInvocation = true)
},
put = {
@CachePut(cacheNames = "Users", key="#result.name"),
@CachePut(cacheNames = "Users", key="#result.email")
}
)
User save(User user);
注意:注意@CacheEvict 注释上的beforeInvocation 属性以及@CachePuts 的用户
但是,您可能更喜欢根据需要将实体延迟添加到缓存中。
虽然,您会假设实体被频繁访问/使用,因为您的 repo 上的 save 方法刚刚被调用,因此依赖您的基础数据存储(例如 GemFire)来设置额外的驱逐(基于溢出)/expiration(基于 LRU)设置,从而更好地管理您的系统资源(例如内存),同时仍保持最佳应用程序性能。
值得深思。
希望这会有所帮助。