16

我有一个接受 DTO 并返回一些结果的服务:

@Override
public int foo(Bar bar) {
    ....
}

条形如下(简化):

public class Bar {
    public int id;
    public String name;
    public String baz;

    @Override
    public int hashCode() {
        //this is already being defined for something else
        ...
    }

    @Override
    public boolean equals(Object o) {
        //this is already being defined for something else
        ...
    }
}

我想在 foo 方法上使用 @Cacheable;但是,我想对 id 和 name 属性进行哈希处理,而不是 baz。有没有办法做到这一点?

4

5 回答 5

44

您也可以使用这种方法

@Override
@Cacheable(key="{#bar.name, #bar.id}")
public int foo(Bar bar) {
    ....
}

建议不要在多个方法参数上使用 hashcode 作为键 @Cacheable 键

于 2014-06-12T20:19:09.177 回答
16

是的,您可以按照以下几行指定使用 Spring-EL 表达式:

@Override
@Cacheable(key="#bar.name.concat('-').concat(#bar.id)")
public int foo(Bar bar) {
    ....
}

或在 bar 上定义修改后的 hashCode 并调用:

@Override
@Cacheable(key="#bar.hashCodeWithIdName")
public int foo(Bar bar) {
    ....
}
于 2012-11-14T15:51:11.210 回答
2

您可以使用 Spring SimpleKey 类

@Cacheable(value = "barCache", key = "new org.springframework.cache.interceptor.SimpleKey(#bar.id, #bar.name)")
于 2019-11-20T10:19:49.140 回答
1

@Biju 和 @vsingh 的两个答案都是正确的;Bar但如果您尝试缓存的对象很复杂,或者该foo方法包含大量参数,使用 SpEL 可能不是生成密钥的最理想解决方案,我想再添加一个替代方案。

或者,您可能要考虑keyGenerator.

例子:

@Override
@Cacheable(value="barCahceKey", keyGenerator="barKeyGenerator")
public int foo(Bar bar) {
  ....
}

@Component
public class BarKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object o, Method method, Object... objects) {
      // TODO logic to generate unique key
      return "Bar_Key_Generator_With_Params_etc";
    }
}

使用这种方法,您可以完全灵活地构建密钥。

密钥生成器 API

于 2017-08-23T14:33:11.170 回答
-1

来自同一个Object的keys,可以使用object.hashCode(),所以不需要一一指定特定keys

@Override
@Cacheable(key="#bar.hashCode()")
public int foo(Bar bar) {
    ....
}

或者,如果您有一个对象和另一个键

@Override
@Cacheable(key="{#bar.hashCode(), #anotherKey}")
public int foo(Bar bar) {
    ....
}

我认为这是一个更好的解决方案。

于 2019-02-28T05:32:32.573 回答