我正在尝试使用带有guice模块的String Cache抽象机制。 我创造了拦截器:
CacheManager cacheManager = createCacheManager(); 绑定(CacheManager.class).toInstance(CacheManager中);
AppCacheInterceptor interceptor = new AppCacheInterceptor(
cacheManager,
createCacheOperationSource()
);
bindInterceptor(
Matchers.any(),
Matchers.annotatedWith(Cacheable.class),
interceptor
);
bindInterceptor(
Matchers.any(),
Matchers.annotatedWith(CacheEvict.class),
interceptor
);
然后,实现了Strings Cache接口和CacheManager,最后使用@Cachable和@CacheEvict注释了我的DAO类:
public class DaoTester {
QssandraConsumer qs;
@CachePut(value = "cached_consumers", key = "#consumer.id")
public void save(QssandraConsumer consumer) {
qs = consumer;
}
@Cacheable(value = "cached_consumers")
public QssandraConsumer get(String id) {
if (id != null) {
qs.getId();
}
return qs;
}
@CacheEvict(value = "cached_consumers", key = "#consumer.id")
public void remove(QssandraConsumer consumer) {
qs = consumer;
}}
缓存很好 - 这里没有问题,但是当我试图逐出(在这个例子中调用remove方法)时,evrything崩溃了,我看到了:
线程“main”中的异常org.springframework.expression.spel.SpelEvaluationException:EL1007E:(pos 10):在null上找不到字段或属性“id” 在org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:205) 在org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72) 在org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57) 在org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93) 在org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:88) 在org.springframework.cache.interceptor.ExpressionEvaluator.key(ExpressionEvaluator.java:80) 在org.springframework.cache.interceptor.CacheAspectSupport $ CacheOperationContext.generateKey(CacheAspectSupport.java:464) 在org.springframework.cache.interceptor.CacheAspectSupport.inspectCacheEvicts(CacheAspectSupport.java:260) 在org.springframework.cache.interceptor.CacheAspectSupport.inspectAfterCacheEvicts(CacheAspectSupport.java:232) 在org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:215) 在org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:66) 在qiwi.qommon.deployment.dao.DaoTester.main(DaoTester.java:44) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在java.lang.reflect.Method.invoke(Method.java:597) 在com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
这里有什么问题?! BTW,缓存对象是:
public class QssandraConsumer implements Identifiable<String> {
private String id;
private String host;
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (null == object) {
return false;
}
if (!(object instanceof QssandraConsumer)) {
return false;
}
QssandraConsumer o = (QssandraConsumer) object;
return
Objects.equal(id, o.id)
&& Objects.equal(host, o.host);
}
@Override
public int hashCode() {
return Objects.hashCode(
id, host
);
}
@Override
public String toString() {
return Objects.toStringHelper(this)
.addValue(id)
.addValue(host)
.toString();
}
}
答案 0 :(得分:0)
最后我弄清楚问题的原因是什么:
当注入一个使用注释的类(被拦截,如@Cachable
或@CacheEvict
)时,Guice增强了类(AOP在运行时进行字节码修改)。因此,CacheInterceptor
尝试评估key = "#consumer.id"
时失败,因为无法在增强类中找到参数名称(请参阅:LocalVariableTableParameterNameDiscoverer#inspectClass
)。
所以它在开箱即用的Guice中不起作用。
在春天,代理类被创建 - 所以这里没有问题。