メソッドがnull値を返す場合、このようなメソッドの@Cacheableアノテーションに結果をキャッシュしないことを指定する方法はありますか?
@Cacheable(value="defaultCache", key="#pk")
public Person findPerson(int pk) {
return getSession.getPerson(pk);
}
更新:昨年11月のnull値のキャッシュに関して提出されたJIRAの問題は次のとおりです。まだ解決されていません: [#SPR-8871] @Cachable条件は戻り値の参照を許可する必要があります
Hooray、Spring 3.2の時点で、フレームワークはSpring SPELとunless
を使用してこれを許可しています。 Cacheableを取り巻くJavaドキュメントからの注意:
パブリック抽象文字列
メソッドキャッシュの拒否に使用されるSpring Expression Language(SpEL)属性。
Condition()とは異なり、この式はメソッドが呼び出された後に評価されるため、結果を参照できます。デフォルトは「」です。これは、キャッシングが拒否されないことを意味します。
重要な点は、メソッドが呼び出された後にunless
が評価されることです。キーがすでにキャッシュにある場合、メソッドは実行されないため、これは完全に理にかなっています。
したがって、上記の例では、次のように注釈を付けるだけです(#resultを使用してメソッドの戻り値をテストできます)。
@Cacheable(value="defaultCache", key="#pk", unless="#result == null")
public Person findPerson(int pk) {
return getSession.getPerson(pk);
}
この状態は、ヌルのキャッシングを許可するEhcacheなどのプラグ可能なキャッシュ実装の使用から生じると想像します。ユースケースのシナリオに応じて、これは望ましい場合と望ましくない場合があります。
updateこの回答は現在古くなっています。Spring3.2以降ではTech Tripの answer 、OP:自由にマークしてください受け入れられました。
_@CacheEvict
_パラメーター beforeInvocation をfalseに設定してメソッドを呼び出した後に実行できる条件付きのキャッシュエビクションがSpringにある場合でも、それは可能だとは思いません。デフォルト値)CacheAspectSupport
クラスを調べると、戻り値がinspectAfterCacheEvicts(ops.get(EVICT));
呼び出しの前にどこにも格納されていないことがわかります。
_protected Object execute(Invoker invoker, Object target, Method method, Object[] args) {
// check whether aspect is enabled
// to cope with cases where the AJ is pulled in automatically
if (!this.initialized) {
return invoker.invoke();
}
// get backing class
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target);
if (targetClass == null && target != null) {
targetClass = target.getClass();
}
final Collection<CacheOperation> cacheOp = getCacheOperationSource().getCacheOperations(method, targetClass);
// analyze caching information
if (!CollectionUtils.isEmpty(cacheOp)) {
Map<String, Collection<CacheOperationContext>> ops = createOperationContext(cacheOp, method, args, target, targetClass);
// start with evictions
inspectBeforeCacheEvicts(ops.get(EVICT));
// follow up with cacheable
CacheStatus status = inspectCacheables(ops.get(CACHEABLE));
Object retVal = null;
Map<CacheOperationContext, Object> updates = inspectCacheUpdates(ops.get(UPDATE));
if (status != null) {
if (status.updateRequired) {
updates.putAll(status.cUpdates);
}
// return cached object
else {
return status.retVal;
}
}
retVal = invoker.invoke();
inspectAfterCacheEvicts(ops.get(EVICT));
if (!updates.isEmpty()) {
update(updates, retVal);
}
return retVal;
}
return invoker.invoke();
}
_
Springアノテーションの場合
@Cacheable(value="defaultCache", key="#pk",unless="#result!=null")
動作しません、あなたは試すことができます:
@CachePut(value="defaultCache", key="#pk",unless="#result==null")
わたしにはできる。