带有项目/实体集合的Spring Cache

Cha*_*bel 17 java spring spring-cache

我正在使用Spring Cache,我在其中传递了一组键,返回是一个实体列表.我想让缓存框架理解返回列表中的每个元素都要使用相应的代码进行缓存.目前,似乎关键是整个列表,如果我在后续调用中缺少一个键,它将尝试再次重新加载整个集合.

@Override
@Cacheable(value = "countries")
public List<Country> getAll(List<String>codes) {
    return countryDao.findAllInCodes(codes);
}
Run Code Online (Sandbox Code Playgroud)

另一种可能性是返回是一个映射,同样我希望缓存足够智能,只能查询以前从未查询过的项目,也可以用它的密钥缓存每个项目.

@Override
@Cacheable(value = "countries")
public Map<String,Country> getAllByCode(List<String>codes) {
    return countryDao.findAllInCodes(codes);
}
Run Code Online (Sandbox Code Playgroud)

假设国家类看起来像这样:

class Country{
  String code; 
  String fullName;
  long id;

... // getters setters constructurs etc.. 
}
Run Code Online (Sandbox Code Playgroud)

这可以用Spring Cache吗?

Joh*_*lum 16

事实上,即使使用Spring的缓存抽象,它也是可能,但不是开箱即用(OOTB).基本上,您必须自定义Spring的缓存基础结构(下面进一步说明)

通过默认情况下,Spring的缓存架构采用全@Cacheable方法参数的参数作为缓存的"钥匙",作为解释在这里.当然,你也可以自定义使用一个关键分辨率规划环境地政司表达或用自定义KeyGenerator实现,如解释在这里.

尽管如此,这并没有参数参数的集合或数组以及@Cacheable方法的返回值分解为单独的缓存条目(即基于数组/集合或映射的键/值对).

为此,您需要Spring的 自定义实现CacheManager(取决于您的缓存策略/提供程序)和Cache接口.

注意:具有讽刺意味的是,这将是我第三次回答几乎相同的问题,首先在这里,然后在这里,现在这里,:-).无论如何...

我已经为这个帖子更新/清理了我的例子(有点).

请注意,我的例子扩展和定制ConcurrentMapCacheManager所提供的Spring框架本身.

从理论上说,你可以扩展/自定义任何CacheManager的实现,像Redis的公司春季Redis的数据,这里(),或枢纽的GemFire的 CacheManager春季数据的GemFire,这里().的开源版本匹的GemFire阿帕奇的Geode,其具有相应的弹簧数据的Geode项目,(来源的CacheManager春季数据的Geode,这基本上等同于SD的GemFire).当然,您可以将此技术应用于其他缓存提供商... Hazelcast,Ehcache等.

但是,工作的真正内容是由Spring的Cache接口的自定义实现(或更具体地说,基类)处理 .

无论如何,希望从我的示例中,您将能够弄清楚您在应用程序中需要做什么来满足应用程序的缓存要求.

此外,您可以采用相同的处理方法Maps,但我会将其作为练习留给您,;-).

希望这可以帮助!

干杯,约翰

  • 你好,我们如何实现部分缓存未命中?例如,如果 `fatorial({1,2,3})` 并且只有 1 和 3 不在缓存中,我们希望它实际上只计算 1 和 3。我无法找出如何修改示例代码的方法。谢谢! (2认同)