Spring cache / jsr107:列表/集合参数作为键的一部分 [英] Spring cache/jsr107: list/collection argument as part of the key

查看:76
本文介绍了Spring cache / jsr107:列表/集合参数作为键的一部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一项服务,该服务调用外部系统以通过其外部ID检索某种对象并将其提交回进行更新。而不是一个个地检索对象,而是有一个通用的方法:

I have a service which calls external system to retrieve some kind of objects by their external id as well as submit them back to update. Rather than retrieving objects one by one there is a more generic purpose methods:

public interface ExternalSystem {
    List<ExternalDTO> getObjects(List<String> externalIds);

    void updateObjects(List<ExternalDTO> updates);
}

我想在ExternalSystem调用上放置一个缓存,因为它们相当

I would like put a cache on top of the ExternalSystem calls because they are quite expensive.

在服务的实现中,我可以简单地放入spring注释:

In the implementation of the service I can simply put spring annotations:

@Cacheable("cache-external")
List<ExternalDTO> getObjects(List<String> externalIds) {} 

@CacheEvict(cacheNames="cache-external", allEntries=true)
void updateObjects(List<ExternalDTO> updates);

但是,如果我在externalId之间有很多交集,则这样的缓存将表现得很差,即

However, such a cache will behave very badly in case I have a lot of intersection between externalIds, i.e.


  1. 调用#1 getObjects([1,2,3,4])->由[1,2,3,4放置的缓存]键

  2. 调用#2 getObjects([1,2,3,4,5])->通过[1,2,3,4,5]键放置的缓存

  3. Call#3 getObjects([6,7,8,9])->通过[6,7,8,9]键放置的缓存

  4. Call #4 updateObjects( 1 )->逐出所有缓存,但第三个缓存没有t包含3

  1. Call#1 getObjects([1,2,3,4]) -> cache put by [1,2,3,4] key
  2. Call#2 getObjects([1,2,3,4,5]) -> cache put by [1,2,3,4,5] key
  3. Call#3 getObjects([6,7,8,9]) -> cache put by [6,7,8,9] key
  4. Call#4 updateObjects(1) -> evict all the caches but the third cache doesn't contain 3

因此,问题是如何实施自定义策略(我认为开箱即用)只会驱逐那些真正应该被驱逐的条目,并以使密钥能够从高速缓存中检索相交对象的方式来创建键?

So, the question is how to implement the custom strategy (I assume it's not doable out-of the box) which will evict only those entries which really should be evicted and will make the keys such a way that intersecting objects are retrieved from the cache?

已更新。 >我发现了两个类似的问题:

Upd. I've found two similar questions:



  1. using-spring-cache -on-methods-that-take-an-array-or-collection


  1. spring-cache-abstraction-with-multi-value-queries
  2. using-spring-cache-on-methods-that-take-an-array-or-collection
  3. spring-cacheable-methods-with-lists

Upd2。
这与我想要的东西类似,除了我将为集合中的每个项目放入String和ExternalDTO缓存对中。
element-level-对列表进行缓存

推荐答案

对我来说,此配置可以正常工作。
这是我代码的混淆版本。

For me it worked fine with this config. This is a obfuscated version of my code.

@Cacheable(cacheNames = "test", key = "#p0")
public List<String> getTestFunction(List<String> someIds) {



getTestFunction(Arrays.asList("A","B","C"));



2020-04-02 15:12:35.492 TRACE 18040 --- [Test worker] o.s.cache.interceptor.CacheInterceptor   : Computed cache key '[A, B, C]' for operation Builder[public java.util.List org.Main.getTestFunction(java.util.List)] caches=[test] | key='#p0' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'

您看到它隐含了字符串

... Computed cache key '[A, B, C]' ...

我的设置:
/resources/ehcache.xml

My setup: /resources/ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <cache name="test"
           maxBytesLocalHeap="1M"
           timeToLiveSeconds="300"/>
</ehcache>

gradle.build

gradle.build

plugins {
    id "org.springframework.boot" version "2.2.4.RELEASE"
    ....
}
dependencies {
    implementation "org.springframework.boot:spring-boot-starter-cache"
    implementation "org.ehcache:ehcache:3.8.1"
    ...
}

这篇关于Spring cache / jsr107:列表/集合参数作为键的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆