[SPRING] Cacheable 주석의 조건에서 키를 사용하려면 어떻게해야합니까?
SPRINGCacheable 주석의 조건에서 키를 사용하려면 어떻게해야합니까?
@cacheable 주석을 사용하여 함수의 결과를 캐싱합니다. 3 가지 다른 캐시가 있으며 각각의 키는 메소드에 인수로 연결된 현재 로그인 한 사용자의 사용자 ID입니다. 특정 이벤트에서 특정 사용자 ID로 시작하는 키가있는 모든 캐시 항목을 제거하려고합니다. 예 :
@Cacheable(value = "testCache1", key = "'abcdef'")
캐시 퇴거 주석을 다음과 같이하고 싶습니다.
@CacheEvict(value = "getSimilarVendors", condition = "key.startsWith('abc')")
그러나 이것을 구현하려고하면 오류가납니다.
Property or field 'key' cannot be found on object of type'org.springframework.cache.interceptor.CacheExpressionRootObject' - maybe not public?
이것을 구현하는 올바른 방법은 무엇입니까?
해결법
-
==============================
1.모든 Spring Cache 주석 (즉 @Cacheable, @CacheEvict 등)은 작업 당 1 개의 캐시 항목에서 작동합니다. @CacheEvict는 전체 캐시를 지우는 것을 지원하지만 (allEntries 속성은이 경우 키를 무시하지만) 단일 작업으로 키 패턴을 기반으로 부분 항목 집합을 지우는 것이 선택적 (유능하지 않음) 설명했다.
모든 Spring Cache 주석 (즉 @Cacheable, @CacheEvict 등)은 작업 당 1 개의 캐시 항목에서 작동합니다. @CacheEvict는 전체 캐시를 지우는 것을 지원하지만 (allEntries 속성은이 경우 키를 무시하지만) 단일 작업으로 키 패턴을 기반으로 부분 항목 집합을 지우는 것이 선택적 (유능하지 않음) 설명했다.
이것의 주된 이유는 evict (key : Object) 메소드가 단일 키 인수를 취하는 Spring Cache 인터페이스 추상화 자체입니다. 그러나 기술적으로 실제로는 기본 캐시 구현 (예 : GemfireCache)에 따라 달라지며, 이는 특정 패턴과 일치하는 모든 항목에 대해 퇴출을 지원해야합니다. 일반적으로 대부분의 캐시에는 해당되지 않습니다 (예 : GemFire가 아닌 경우). Google Guava 캐시 용이 아니라 여기 및 여기 참조).
그것은 당신이 절대적으로 당신의 목표를 달성 할 수 없다는 말은 아닙니다. 그것은 바로 out-of-the-box 지원되는 무언가가 아닙니다.
흥미로운 점은 접근 방식에 기술적 인 문제가 없다는 것입니다. 조건에 따라 원하는대로 정렬 할 수 있습니다. 캐시 퇴거는 키가 조건을 충족하는 경우에만 발생합니다. 그러나 @CacheEvict 주석이 달린 메서드는 "키"가 누락되어 오류가 발생합니다. 그래서, 다음과 같은 것이 당신의 상태에서 SpEL을 만족시킬 것입니다 ...
@CacheEvict(condition = "#key.startsWith('abc')") public void someMethod(String key) { ... }
그러나이 경우 인수로 키를 지정해야합니다. 그러나 특정 키를 원하지 않으면 여러 키와 일치하는 패턴을 원하게됩니다. 그래서, 조건을 잊어 버리고 그냥 사용하십시오 ...
@CacheEvict public void someMethod(String keyPattern) { ... }
예를 들어, Guava를 캐싱 공급자로 사용하면 GuavaCache를 확장하는 "사용자 지정"구현을 제공해야합니다.
public class CustomGuavaCache extends org.springframework.cache.guava.GuavaCache { protected boolean isMatch(String key, String pattern) { ... } protected boolean isPattern(String key) { ... } @Override public void evict(Object key) { if (key instanceof String && isPattern(key.toString()))) { Map<String, Object> entries = this.cache.asMap(); Set<String> matchingKeys = new HashSet<>(entries.size()); for (String actualKey : entries.keySet()) { if (isMatch(actualKey, key.toString()) { matchingKeys.add(actualKey); } } this.cache.invalidateAll(matchingKeys); } else { this.cache.invalidate(key); } } }
이제 GuavaCacheManager를 확장하여 "사용자 정의"GuavaCache (CustomGuavaCache)를 플러그인하십시오.
public class CustomGuavaCacheManager extends org.springframework.cache.guava.GuavaCacheManager { @Override protected Cache createGuavaCache(String name) { return new CustomGuavaCache(name, createNativeGuavaCache(name), isAllowNullValues()); } }
이 접근법은 Guava의 Cache의 invalidateAll (keys : Iterable) 메소드를 이용합니다. 물론, 자바의 Regex 지원을 사용하여 isMatch (key, pattern) 메소드에서 제거 할 원하는 키에 "일치"를 수행 할 수 있습니다.
그래서, 나는 이것을 테스트하지는 않았지만, 이것 (또는 비슷한)은 (거의) 당신이 원하는 것을 달성해야합니다 (손가락이 엇갈린 ;-)
희망이 도움이!
건배, 남자
from https://stackoverflow.com/questions/32460606/how-do-i-use-the-key-in-a-condition-in-cacheable-annotation by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] java.lang.NoSuchMethodError : org.springframework.util.ClassUtils.forName (Ljava) (0) | 2019.02.15 |
---|---|
[SPRING] Maven - 유물 누락 (0) | 2019.02.15 |
[SPRING] Ajax를 사용하여 Spring 보안으로 로그인하기 (0) | 2019.02.15 |
[SPRING] web.xml에서 HttpServlet과 Spring Application Context를 연결하는 방법은 무엇입니까? (0) | 2019.02.15 |
[SPRING] Spring에서 application.properties를 사용하여 프로파일을 설정하는 방법은 무엇입니까? (0) | 2019.02.15 |