如何让以下工作: - 一个spring bean,它有一个应该用@Cacheable注释缓存的方法 - 另一个为缓存创建密钥的spring bean(KeyCreatorBean)。
所以代码看起来像这样。
@Inject
private KeyCreatorBean keyCreatorBean;
@Cacheable(value = "cacheName", key = "{@keyCreatorBean.createKey, #p0}")
@Override
public List<Examples> getExamples(ExampleId exampleId) {
...
但是上面的代码不起作用:它提供以下异常:
Caused by: org.springframework.expression.spel.SpelEvaluationException:
EL1057E:(pos 2): No bean resolver registered in the context to resolve access to bean 'keyCreatorBean'
答案 0 :(得分:2)
我检查了底层缓存解析实现,似乎没有一种简单的方法来注入BeanResolver
,这是解析bean和评估像@beanname.method
这样的表达式所必需的。
因此,我也建议采用@micfra推荐的方式。
沿着他所说的,沿着这些行拥有一个KeyCreatorBean,但在内部将它委托给你在应用程序中注册的keycreatorBean:
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);
}
}
答案 1 :(得分:0)
如果你有一个静态类函数,它将像这样工作
@Cacheable(value = "cacheName", key = "T(pkg.beans.KeyCreatorBean).createKey(#p0)")
@Override
public List<Examples> getExamples(ExampleId exampleId) {
...
}
与
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);
}
}