Using Spring beans as a key with @Cacheable annotation

笑着哭i 提交于 2019-12-03 20:31:38

问题


How to make following to work: - a spring bean that has a method that should be cached with @Cacheable annotation - another spring bean that creates keys for the cache (KeyCreatorBean).

So the code looks something like this.

@Inject
private KeyCreatorBean keyCreatorBean;

@Cacheable(value = "cacheName", key = "{@keyCreatorBean.createKey, #p0}")
@Override
public List<Examples> getExamples(ExampleId exampleId) {
  ...

However the above code doesn't work: it gives following exception:

Caused by: org.springframework.expression.spel.SpelEvaluationException: 
    EL1057E:(pos 2): No bean resolver registered in the context to resolve access to bean 'keyCreatorBean'

回答1:


I checked the underlying cache resolution implementation, there doesn't appear to be a simple way to inject in a BeanResolver which is required for resolving the beans and evaluating expressions like @beanname.method.

So I would also recommend a somewhat hacky way along the lines of one which @micfra has recommended.

Along what he has said, have a KeyCreatorBean along these lines, but internally delegate it to the keycreatorBean that you registered in your application:

package pkg.beans;

import org.springframework.stereotype.Repository;

public class KeyCreatorBean  implements ApplicationContextAware{
    private static ApplicationContext aCtx;
    public void setApplicationContext(ApplicationContext aCtx){
        KeyCreatorBean.aCtx = aCtx;
    }


    public static Object createKey(Object target, Method method, Object... params) {
        //store the bean somewhere..showing it like this purely to demonstrate..
        return aCtx.getBean("keyCreatorBean").createKey(target, method, params);
    }

}



回答2:


In the case you have a static class function, it will work like this

@Cacheable(value = "cacheName", key = "T(pkg.beans.KeyCreatorBean).createKey(#p0)")
@Override
public List<Examples> getExamples(ExampleId exampleId) {
  ...
}

with

package pkg.beans;

import org.springframework.stereotype.Repository;

public class KeyCreatorBean  {

    public static Object createKey(Object o) {
        return Integer.valueOf((o != null) ? o.hashCode() : 53);
    }

}


来源:https://stackoverflow.com/questions/11396911/using-spring-beans-as-a-key-with-cacheable-annotation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!