@Cacheable 주석에서 null 값을 캐시하지 않도록 Spring 캐시에 어떻게 지시합니까?
메서드가 null 값을 반환하면 이와 같은 메서드에 대해 @Cacheable 주석에 결과를 캐시하지 않도록 지정하는 방법이 있습니까?
@Cacheable(value="defaultCache", key="#pk")
public Person findPerson(int pk) {
return getSession.getPerson(pk);
}
업데이트 : 다음은 지난 11 월 null 값 캐싱과 관련하여 제출 된 JIRA 문제입니다. 아직 해결되지 않았습니다. [# SPR-8871] @Cachable 조건은 반환 값 참조를 허용해야합니다.-Spring Projects Issue Tracker
만세, 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);
}
이 조건은 null 캐싱을 허용하는 Ehcache와 같은 플러그 가능한 캐시 구현을 사용하여 발생한다고 생각합니다. 사용 사례 시나리오에 따라 이것은 바람직하거나 바람직하지 않을 수 있습니다.
갱신 이 대답은 봄 3.2, 이제 구식이 나중에 기술 여행의 참조되는 대답을 , 영업 이익은 : 접수로 표시 주시기 바랍니다.
나는 그것이 가능하다고 생각하지 않는다 (Spring에 조건부 Cache eviction이 있지만 @CacheEvict
매개 변수 beforeInvocation 이 기본값 인 false로 설정된 메서드 호출 후에 실행할 수 있음 ) 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")
그것은 나를 위해 작동합니다.
'IT TIP' 카테고리의 다른 글
HttpResponseMessage와 HttpResponseException의 차이점은 무엇입니까? (0) | 2020.12.15 |
---|---|
ASP.NET MVC 및 ASP.NET Web Api에서 작동하도록 Autofac을 구성 할 수 있습니까? (0) | 2020.12.15 |
C ++에 대한 컨텍스트의 단일화 란 무엇입니까? (0) | 2020.12.15 |
JavaScript에서 Object.freeze 또는 Object.seal의 반대 (0) | 2020.12.15 |
Python에서 개인 및 보호 메서드 상속 (0) | 2020.12.15 |