使用带有 @Cacheable 注释的 Spring bean 作为键
Posted
技术标签:
【中文标题】使用带有 @Cacheable 注释的 Spring bean 作为键【英文标题】:Using Spring beans as a key with @Cacheable annotation 【发布时间】:2012-07-08 23:04:14 【问题描述】:如何使以下工作: - 一个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'
【问题讨论】:
试试#keyCreatorBean.method
,而不是@keyCreatorBean.method
。只是随机猜测。
有点相关的问题:***.com/questions/5749730/…
你可以试试这个:***.com/a/8142249/799562 <cache:annotation-driven key-generator="myKeyGenerator"/>
但需要实现org.springframework.cache.interceptor.KeyGenerator
。
我就这个问题向 SpringSource 发了一张票:jira.springsource.org/browse/SPR-9578
另一个相关问题:***.com/q/5743565/1431,这里的问题在于 Spring Security 注释,但给定的解决方法似乎不适用于我的情况。
【参考方案1】:
如果你有一个静态类函数,它会像这样工作
@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);
【讨论】:
我需要使用spring bean,而不是静态工厂方法。 使用@keyCreatorBean.createKey(#p0)
失败,就像您的情况一样。也许上下文在缓存注释处理时不知道 bean 实例?周围有什么春季大师?【参考方案2】:
我检查了底层缓存解析实现,似乎没有一种简单的方法可以注入 BeanResolver
,这是解析 bean 和评估像 @beanname.method
这样的表达式所必需的。
所以我也会推荐一种类似于@micfra 推荐的方式的有点hacky 的方式。
按照他所说的,按照这些思路拥有一个 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);
【讨论】:
以上是关于使用带有 @Cacheable 注释的 Spring bean 作为键的主要内容,如果未能解决你的问题,请参考以下文章
详解Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用
Spring Boot Cacheable除非带有List的结果