10

Say I have 2 different bean methods which I want to cache by EhCache:

@Component
public class StatService {

@Cacheable(value = "statCalc")
public int getMeth1(int param) {
    // LOGIC1
}

@Cacheable(value = "statCalc")
public int getMeth2(int param) {
    // LOGIC2
}
}

I want to reside them in same cache - ehcache.xml:

<cache name="statCalc"
       ...
/>

The problem is that cache key is generated by input parameters and not by method signature, thus getMeth2(1) can return value cached by getMeth1(1).

What is the easiest way to build key using method name?

P.S. Please, don't mention the fact that using same cache for different methods could be wrong, just help to solve this problem.

corvax
  • 1,095
  • 1
  • 10
  • 35

2 Answers2

11

Spring Cache abstraction allows you to use SpeL to specify the cache key. For example you can use a method name , parameter values etc.

For example

@Component
public class StatService {

   @Cacheable(value="statCalc",key="#root.method.name.concat(':').concat(#param)")
   public int getMeth1(int param) {
      // LOGIC1
   }

   @Cacheable(value="statCalc",key="#root.method.name.concat(':').concat(#param)")
   public int getMeth2(int param) {
   // LOGIC2
   }
}

For the method call getMeth1(5) the key will be getMethod1:5 For method call getMethod1(0) key will be getMethod1:0

For method call getMeth2(3) the key will be getMethod2:3. This allows you to cache results for different parameters

sjngm
  • 12,423
  • 14
  • 84
  • 114
ekem chitsiga
  • 5,523
  • 2
  • 17
  • 18
7

Use custom KeyGenerator, e.g.

public class CustomKeyGenerator implements KeyGenerator{
    @Override
    public Object generate(Object target, Method method, Object... params) {
        StringBuilder key = new StringBuilder();
        //include method name in key
        key.append(method.getName());
        if (params.length > 0) {
            key.append(';');
            for (Object argument : params) {
                key.append(argument);
                key.append(';');
            }
        }
        return key.toString();
    }
}

Register key generator as a bean and add @CacheKeyStrategy("keyGeneratorBeanName") annotation to the cacheable methods

Evgeny
  • 2,483
  • 1
  • 17
  • 24