1

Guice モジュールで String Cache 抽象化メカニズムを使用しようとしています。インターセプターを作成しました:

CacheManager cacheManager = createCacheManager(); bind(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 を実装し、最後に DAO クラスに @Cachable と @CacheEvict のアノテーションを付けました。

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メソッドを呼び出します)、すべてがクラッシュし、次のように表示されます:

スレッド「メイン」org.springframework.expression.spel.SpelEvaluationException での例外: EL1007E:(pos 10): フィールドまたはプロパティ 'id' が org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference) の null で見つかりません.java:205) org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72) で org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57) で org. org.springframework.cache.interceptor.ExpressionEvaluator. key(ExpressionEvaluator.java:80) at org.springframework.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)、sun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブ メソッド)、sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)、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) で

ここで何が問題なのですか?! ところで、キャッシュされたオブジェクトは次のとおりです。

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();
}

}

4

1 に答える 1

0

最後に、問題の原因を突き止めました: アノテーションを使用するクラスを注入するとき (@Cachableまたはのようにインターセプト@CacheEvictされます)、Guice はクラスを拡張します (AOP は実行時にバイトコードを変更します)。そのため、拡張クラスで引数名が見つからなかったためCacheInterceptor、評価しようとすると失敗しました (参照: )。そのため、そのままでは Guice では機能しません。春にプロキシクラスが作成されるので、ここでは問題ありません。key = "#consumer.id"LocalVariableTableParameterNameDiscoverer#inspectClass

于 2013-04-08T17:06:18.603 に答える