Генератор ключей кеширования Spring

Я только начал работать над кешированием Spring.

Мой метод обслуживания...

@Override
@Cacheable(value="profile", **key**="personId" )
public String cpuService2(Long personId, String personAddress){
    return "CachedMessage";
}

Без ключевого предложения не выдает исключение и предполагает, что оба параметра автоматически генерируются для кэширования, но с ключом. Когда я вызываю этот метод, выдает исключение как...

Exception in thread "main" org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'personId' cannot be found on object of type 'org.springframework.cache.interceptor.CacheExpressionRootObject'
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:246)
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:112)
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:107)
        at org.springframework.expression.spel.ast.OpGT.getValueInternal(OpGT.java:37)
        at org.springframework.expression.spel.ast.OpGT.getValueInternal(OpGT.java:29)
        at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:102)
        at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:98)
        at org.springframework.cache.interceptor.ExpressionEvaluator.condition(ExpressionEvaluator.java:99)
        at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.isConditionPassing(CacheAspectSupport.java:462)
        at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.isConditionPassing(CacheAspectSupport.java:456)
        at org.springframework.cache.interceptor.CacheAspectSupport.inspectCacheables(CacheAspectSupport.java:292)
        at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:199)
        at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:66)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at $Proxy5.cpuService3(Unknown Source)
        at pack100_cache.pack020CacheKey.TestSimpleBean.main(TestSimpleBean.java:34)

Искал документацию, но не понял. Надеюсь, кто-нибудь решит эту проблему.


person user3561481    schedule 24.04.2014    source источник


Ответы (2)


Вы пропустили # перед personId

@Override
@Cacheable(value="profile", key="#personId" )
public String cpuService2(Long personId, String personAddress){
    return "CachedMessage";
}

В главе, посвященной абстракции кэширования, есть множество примеров того, что вы пытаясь сделать.

person Stephane Nicoll    schedule 24.04.2014
comment
Спасибо. Имелось в виду какой-то блог с неправильным кодом. - person user3561481; 28.04.2014
comment
Для меня, после указания только одной кавычки, это сработало, key='#personId' - person Satish Patro; 24.05.2019
comment
Я сомневаюсь, что это так, это использует #personId в качестве ключа (буквально, это не будет применять выражение spel) - person Stephane Nicoll; 27.05.2019

Когда все становится сложнее, SpEL, возможно, не является идеальным решением, когда речь идет о простом понимании алгоритма, используемого для генерации ключа. Вы можете использовать Java для генерации ключа:

@Component
public class FooGenerator implements KeyGenerator {
    @Override
    public Object generate(Object target, Method method, Object... params) {
        String param = "";

        if (params.length == 2) {
            if (params[0] instanceof String) {
                param = (String) params[0];

        String key = "FooKeyEquatesTo" + param;
        return key;
}

Затем вы можете подключить этот генератор ключей туда, где он вам нужен:

@Cacheable(value = "nameofmycachearea", keyGenerator="fooGenerator")
person Marged    schedule 13.01.2015
comment
Привет! не могли бы вы мне помочь, пожалуйста? Извините, что пишу сюда. У меня проблема с созданием собственного генератора ключей. Как получить метод getAllEntities() без параметров, возвращаемых ключом someKey? (последний вопрос у меня в профиле) - person Vladislav Solopov; 06.05.2019