1

我在 Springboot 中使用 JSR107 缓存。我有以下方法。

@CacheResult(cacheName = "books.byidAndCat")
public List<Book> getAllBooks(@CacheKey final String bookId, @CacheKey final BookCategory bookCat) {

return <<Make API calls and get actual books>>
}

第一次进行实际的 API 调用,第二次加载缓存没有问题。我可以看到日志的以下部分。

Computed cache key SimpleKey [cb5bf774-24b4-41e5-b45c-2dd377493445,LT] for operation CacheResultOperation[CacheMethodDetails ...

但问题是我想加载缓存而不进行第一次 API 调用,只需要像下面这样填充缓存。

String cacheKey  = SimpleKeyGenerator.generateKey(bookId, bookCategory).toString();     
        cacheManager.getCache("books.byidAndCat").put(cacheKey, deviceList);

当我检查时,缓存键的哈希码在两种情况下都是相同的,但它正在进行 API 调用。如果两种情况下的哈希码相同,为什么不考虑缓存就进行 API 调用?

在调试 spring 类时发现,org.springframework.cache.interceptor.SimpleKeyGenerator 与缓存键生成一起使用,即使 @CacheResult 在那里。 编辑并增强问题:

除此之外,如果 getAllBooks 具有重载方法,然后通过单独的重载方法调用此缓存方法,在这种情况下,方法缓存也不起作用。

4

2 回答 2

1

我不是 Spring 上下文中 JSR107 注释的专家。我改用 Spring Cache 注释。

使用 JSR107 时,使用的密钥是GeneratedCacheKey. 这就是您应该放入缓存中的内容。不是toString()它的。请注意,SimpleKeyGenerator它不返回GeneratedCacheKey. SimpleKey当使用自己的缓存注释而不是 JSR-107 时,它返回一个这是 Spring 使用的键。对于 JSR-107,您需要一个SimpleGeneratedCacheKey.

然后,如果您想预加载缓存,只需getAllBooks在需要之前调用它。

如果您想以其他方式预加载缓存,a@javax.cache.annotation.CachePut应该可以解决问题。有关示例,请参见其 javadoc。

于 2018-05-26T01:00:58.050 回答
0

正如@Henri 建议的那样,我们可以使用缓存。但为此,我们需要方法。通过下面我们可以更新缓存非常类似于缓存,

//重载方法id和cat都可用。

List<Object> bookIdCatCache = new ArrayList<>();
    bookIdCatCache.add(bookId);
    bookIdCatCache.add(deviceCat);
    Object bookIdCatCacheKey  = SimpleKeyGenerator.generateKey(bookIdCatCache.toArray(new Object[bookIdCatCache.size()]));
    cacheManager.getCache("books.byidAndCat").put(bookIdCatCacheKey , bookListWithIdAndCat);

//重载的方法只有id

List<Object> bookIdCache = new ArrayList<>();
        String nullKey          = null
        bookIdCache.add(bookId);
        bookIdCache.add(nullKey);
        Object bookIdCacheKey  = SimpleKeyGenerator.generateKey(bookIdCache.toArray(new Object[bookIdCache.size()]));
        cacheManager.getCache("books.byidAndCat").put(bookIdCacheKey , bookListWithId);

//不正确(我之前的实现)

String cacheKey  = SimpleKeyGenerator.generateKey(bookId, bookCategory).toString();

//正确(这是从春天得到的)

Object cacheKey  = SimpleKeyGenerator.generateKey(bookIdCatCache.toArray(new Object[bookIdCatCache.size()]));
于 2018-05-28T08:27:10.503 回答