java Spring @Cacheable 仍然执行复杂的键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11889428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 06:47:40  来源:igfitidea点击:

Spring @Cacheable with complex keys still executed

javaspringcaching

提问by checklist

I have the following for the usage of a @Cacheable in spring (3.1):

对于在 spring (3.1) 中使用 @Cacheable,我有以下几点:

spring:

春天:

<?xml   version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
    xmlns:sec="http://www.springframework.org/schema/security"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xmlns:mongo="http://www.springframework.org/schema/data/mongo"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 
                            http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
                            http://www.springframework.org/schema/data/mongo
                            http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
                            http://www.springframework.org/schema/cache 
                            http://www.springframework.org/schema/cache/spring-cache.xsd
                            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
                            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
                            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
                            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">

<cache:annotation-driven />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache" />
<!-- Ehcache library setup -->
<bean id="ehcache"  class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
    p:config-location="classpath:ehcache.xml" />

Maven:

马文:

    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache-core</artifactId>
        <version>2.5.3</version>
    </dependency>

The to be cached method:

要缓存的方法:

@Cacheable(value="cahceName", key="concat(#param1).concat(‘-').concat(#param2)")
    public String cachedMethod(String param1,String param2)

Alas, when I debug the code, I see that the cached method gets called more than once even when param1 and param2 are the same (i.e the cahce is not used).

唉,当我调试代码时,我发现即使 param1 和 param2 相同(即未使用 cahce),缓存方法也被多次调用。

Any ideas?

有任何想法吗?

回答by Biju Kunjummen

The key does not appear correct -

密钥显示不正确 -

You may have meant - @Cacheable(value="cacheName", key="#param1.concat(‘-').concat(#param2)")

你可能是说—— @Cacheable(value="cacheName", key="#param1.concat(‘-').concat(#param2)")

Further, if the compilation is done without debug information, the param1, param2 argument names will not be available to expression evaluator. Instead you can refer to them using p0, p1 etc this way:

此外,如果在没有调试信息的情况下完成编译,则表达式评估器将无法使用 param1、param2 参数名称。相反,您可以通过以下方式使用 p0、p1 等来引用它们:

@Cacheable(value="cahceName", key="#p0.concat('-').concat(#p1)")

@Cacheable(value="cahceName", key="#p0.concat('-').concat(#p1)")

Update:

更新:

I have a one page test here which demonstrates how this works - https://gist.github.com/3315275

我在这里有一个一页测试,它演示了这是如何工作的 - https://gist.github.com/3315275

回答by Leszek Jasek

In my case, the problem was caused by using the wrong configuration of the cache provider (Caffeine):

就我而言,问题是由于使用缓存提供程序 ( Caffeine)的错误配置引起的:

@Bean
public Caffeine<Object, Object> caffeineCacheBuilder() {
    return Caffeine.newBuilder()
        .initialCapacity(100)
        .maximumSize(1000)
        .expireAfterAccess(10, TimeUnit.MINUTES)
        .weakKeys(); // cause problems when concatenated keys used
}

As the docs says, weakKeys()method:

正如文档所说,weakKeys()方法:

Specifies that each key (not value) stored in the cache should be wrapped in a WeakReference (by default, strong references are used).

Warning:when this method is used, the resulting cache will use identity ({@code ==}) comparison to determine equality of keys. Its {@link Cache#asMap} view will therefore technically violate the {@link Map} specification (in the same way that {@link IdentityHashMap} does).

指定存储在缓存中的每个键(不是值)都应该包含在 WeakReference 中(默认情况下,使用强引用)。

警告:使用此方法时,生成的缓存将使用标识 ({@code ==}) 比较来确定键的相等性。因此,它的 {@link Cache#asMap} 视图在技术上将违反 {@link Map} 规范(与 {@link IdentityHashMap} 相同)。