无法从Guice DI应用程序中的Spring缓存中退出
我试图将字符串缓存抽象机制与guice模块结合使用。 我创建了拦截器: CacheManager CacheManager=createCacheManager; bindCacheManager.class.toInstancecacheManager无法从Guice DI应用程序中的Spring缓存中退出,spring,caching,guice,Spring,Caching,Guice,我试图将字符串缓存抽象机制与guice模块结合使用。 我创建了拦截器: CacheManager CacheManager=createCacheManager; bindCacheManager.class.toInstancecacheManager AppCacheInterceptor interceptor = new AppCacheInterceptor( cacheManager, createCacheOperationS
AppCacheInterceptor interceptor = new AppCacheInterceptor(
cacheManager,
createCacheOperationSource()
);
bindInterceptor(
Matchers.any(),
Matchers.annotatedWith(Cacheable.class),
interceptor
);
bindInterceptor(
Matchers.any(),
Matchers.annotatedWith(CacheEvict.class),
interceptor
);
然后,实现了字符串缓存接口和缓存管理器,最后用@Cachable和@cacheexecute注释了我的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.ReadPropertyPropertyYorfieldReference.java:205
位于org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternalPropertyOrFieldReference.java:72
位于org.springframework.expression.spel.ast.CompoundExpression.getValueInternalCompoundExpression.java:57
位于org.springframework.expression.spel.ast.SpelNodeImpl.getValueSpelNodeImpl.java:93
位于org.springframework.expression.spel.standard.SpelExpression.getValueSpelExpression.java:88
位于org.springframework.cache.interceptor.ExpressionEvaluator.keyExpressionEvaluator.java:80
位于org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.GenerateKeyCacheApectSupport.java:464
位于org.springframework.cache.interceptor.CacheAspectSupport.InspectCacheReceiveScacheAspectSupport.java:260
位于org.springframework.cache.interceptor.CacheAspectSupport.InspectAfterCacheReceiveScacheAspectSupport.java:232
位于org.springframework.cache.interceptor.CacheAspectSupport.ExecuteCacheApectSupport.java:215
位于org.springframework.cache.interceptor.CacheInterceptor.invokeCacheInterceptor.java:66
位于qiwi.qommon.deployment.dao.DaoTester.mainDaoTester.java:44
在sun.reflect.NativeMethodAccessorImpl.invoke0Native方法中
位于sun.reflect.NativeMethodAccessorImpl.invokeNativeMethodAccessorImpl.java:39
在sun.reflect.DelegatingMethodAccessorImpl.invokeDelegatingMethodAccessorImpl.java:25
位于java.lang.reflect.Method.invokeMethod.java:597
位于com.intellij.rt.execution.application.AppMain.mainAppMain.java:120
这里怎么了?!
顺便说一句,缓存对象是:
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();
}
}最后我找到了问题的原因: 当注入一个使用被截获的注释的类时,比如@Cachable或@cacheexecute Guice增强了类AOP,在运行时修改字节码。因此,当CacheInterceptor尝试计算key=consumer.id时,它失败了,因为在增强类中找不到参数名称请参见:LocalVariableTableParameterNameDiscoverySpectClass。 因此,它不能在开箱即用的情况下工作。 在spring中创建了代理类——因此这里没有问题