【问题标题】:@Cacheble annotation on no parameter method无参数方法上的@Cacheble 注释
【发布时间】:2016-01-27 18:32:54
【问题描述】:

我想在没有参数的方法上添加@Cacheable 注释。在这种情况下,我使用@Cacheable 如下

@Cacheable(value="usercache", key = "mykey")
public string sayHello(){
    return "test"
}

但是,当我调用此方法时,它没有被执行,并且出现如下异常

org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'mykey' cannot be found on type of 'org.springframework.cache.interceptor.CacheExpressionRootObject' - 也许不公开?

请提出建议。

【问题讨论】:

    标签: spring ehcache spelevaluationexception


    【解决方案1】:

    您可以省略 key 参数。然后 Spring 会将带有键 SimpleKey.EMPTY 的值放入缓存中:

    @Cacheable("usercache")
    

    或者(除了使用其他解决方案中概述的 SPEL 之外)您始终可以注入 CacheManager 并手动处理它。

    【讨论】:

    • 如何在单元测试中解决这个问题? stackoverflow.com/questions/50519570/…
    • @Gowrav 可能是 Mockito 干扰?
    • 似乎是这样,我无法绕过,如果 api 有一个参数,它按预期工作,但没有参数有同样的问题,也许我们应该记录一个针对 mockito 的错误
    • @Gowrav 尝试 doReturn(...).when(...)。有时以这种方式重新排序有助于使 Mockito 表现良好。
    【解决方案2】:

    在键中添加#

    @Cacheable(value="usercache", key = "#mykey")
    public string sayHello(){
        return "test"
    }
    

    【讨论】:

    • 如果#mykey 是某处定义的变量,则用于变量替换。但是,它不是,因此会导致空键错误。
    【解决方案3】:

    尝试在mykey 周围添加单引号。这是一个 SPEL 表达式,单引号又使它成为 String

    @Cacheable(value="usercache", key = "'mykey'")
    

    【讨论】:

    • 这应该是正确的答案,因为它完全正确并且直接回答了问题。
    【解决方案4】:

    似乎 Spring 不允许您为 SPEL 中的缓存键提供静态文本,并且默认情况下它不包含键上的方法名称,因此,您可以在当两种方法使用相同的 cacheName 并且没有键时,可能会使用相同的键缓存不同的结果。

    最简单的解决方法是提供方法的名称作为键:

    @Cacheable(value="usercache", key = "#root.methodName")
    public string sayHello(){
    return "test"
    }
    

    这会将sayHello 设置为键。

    如果你真的需要静态键,你应该在类中定义一个静态变量,并使用#root.target

    public static final String MY_KEY = "mykey";
    
    @Cacheable(value="usercache", key = "#root.target.MY_KEY")
    public string sayHello(){
    return "test"
    }
    

    您可以找到here 可以在密钥中使用的 SPEL 表达式列表。

    【讨论】:

    • 您能否解释一下这一行 - 静态键(在您的情况下为 mykey)也没有意义,因为 Spring 已经将缓存绑定到特定方法。那么,如果我不明确提及,将存储在缓存中的密钥是什么
    • @user3534483 抱歉,我对 Spring 使用的默认密钥有误。我已经编辑了答案并添加了正确的信息。
    • “Spring 似乎不允许您为 SPEL 中的缓存键提供静态文本”。这是错误的,因为您可以使用字符串文字。例如。我在生产中使用private static final String CACHE_KEY_ALL = "'##all'"; 并且像魅力一样工作。无论如何,答案很摇滚,所以我不会投反对票
    • @Ruben 为什么我们需要没有参数方法的键?我可以使用 #1 @Cachable("cache1") method1() #2 @Cachable("cache2") method2() 。这是不正确的方式吗?
    • 这是一个部分正确和部分错误的答案。请参阅 Clif 下面的答案。这应该是公认的答案。
    猜你喜欢
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多