Как кэшировать 2 разных метода bean-компонентов в одном и том же ehCache?

Скажем, у меня есть 2 разных метода bean-компонентов, которые я хочу кэшировать с помощью EhCache:

@Component
public class StatService {

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

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

Я хочу разместить их в одном кеше - ehcache.xml:

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

Проблема в том, что ключ кэша генерируется входными параметрами, а не сигнатурой метода, поэтому getMeth2(1) может возвращать значение, кэшированное getMeth1(1).

Каков самый простой способ создать ключ, используя имя метода?

P.S. Пожалуйста, не упоминайте тот факт, что использование одного и того же кеша для разных методов может быть неправильным, просто помогите решить эту проблему.


person corvax    schedule 20.04.2016    source источник
comment
Как генерируется ключ?   -  person Roman C    schedule 20.04.2016
comment
@RomanC Генератор ключей по умолчанию, который использует все входные параметры.   -  person corvax    schedule 20.04.2016


Ответы (2)


Используйте пользовательский KeyGenerator, например.

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();
    }
}

Зарегистрируйте генератор ключей как bean-компонент и добавьте аннотацию @CacheKeyStrategy("keyGeneratorBeanName") к кэшируемым методам.

person Evgeny    schedule 20.04.2016

Абстракция Spring Cache позволяет использовать SpeL для указания ключа кэша. Например, вы можете использовать имя метода, значения параметров и т. д.

Например

@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
   }
}

Для вызова метода getMeth1(5) ключ будет getMethod1:5 Для вызова метода getMethod1(0) ключ будет getMethod1:0

Для вызова метода getMeth2(3) ключом будет getMethod2:3. Это позволяет кэшировать результаты по разным параметрам.

person ekem chitsiga    schedule 20.04.2016