2017-12-21 35 views
0

캐시 용 REST 서비스에 스프링 부트와 hazelcast를 사용하고 있습니다. 사용자 정의 키 생성기로 @Cachable 주석을 사용하여 서비스 계층 (API)에서 캐싱 중입니다. 그것은 오류 시나리오를 처리하기 위해 추가 한 사용자 정의 오류 클래스에 의해 처리되지 않는 사용자 정의 키 생성기 함수에서 RuntimeException을 제외하고 모든 것은 잘 작동합니다. org.springframework.cache.annotation.CachingConfigurerSupport를 확장하고 모든 함수를 오버라이드하여 GET, PUT, EVICT 오류를 처리하는 사용자 정의 오류 클래스 (CacheErrorHandler). 제 경우에는 사용자 정의 customKeyGenerator가 RuntimeException을 throw하면 handleCacheGetError 함수로 침입 할 것으로 예상됩니다. 어떤 설명을해도 내가 누락 된 부분이나 설명을 돕는 것이 스프링 주석 (예 : @Cachable)을 사용하여 캐시 (HAZELCAST 또는 REDIS 등)에 대한 캐싱 오류를 처리하는 올바른 방법입니다. 샘플로스프링 부트를 기반으로 한 REST 서비스, hazelcast를 사용한 스프링 캐싱은 캐시 오류를 처리하지 못함

, 여기

@Cacheable(cacheNames = "TestCache",keyGenerator = "customKeyGenerator") 
public Response getAPIResponse(Integer param1){ 
... 
} 

은 마찬가지로, CachingConfigurerSupport를 확장 내 캐시 구성 클래스는, 다음이

@Configuration 
public class CacheConfiguration extends CachingConfigurerSupport { 
... 

@Override 
    public CacheErrorHandler errorHandler() { 
     return new CustomHZCacheErrorHandler(); 
    } 
... 
} 

모양처럼 내 API 캐싱 모습입니다 CustomHZCacheErrorHandler 보이는

public class CustomHZCacheErrorHandler implements CacheErrorHandler { 
    private static final Logger logger = LoggerFactory.getLogger(CustomHZCacheErrorHandler.class); 

    public CustomHZCacheErrorHandler() { 
    } 

    public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) { 
     logger.warn("Error while getting cache " + cache.getName() + " for Key " + key); 
    } 

    public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) { 
     logger.warn("Error while putting cache " + cache.getName() + " for Key " + key); 
    } 

    public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) { 
     logger.warn("Error while evicting cache " + cache.getName() + " for Key " + key); 
    } 

    public void handleCacheClearError(RuntimeException exception, Cache cache) { 
     logger.warn("Error while clearing cache " + cache.getName()); 
    } 
} 

같은

답변

1

@NRA, Spring Doc,에 따라, CacheErrorHandler은 캐시 공급자가 던진 예외 만 사용합니다. Key Generator는 아니고, 주석 첨부 메소드가 Throw하는 예외도 포함하지 않습니다.

참조하십시오 https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheInvoker.java#L71 MVC 컨트롤러에 대한

은, 봄은 오류를 처리하는 데 도움 주석이 있습니다 @ErrorHandler합니다. https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

MVC를 사용하지 않는 경우 Aspect Bean &을 정의하면 해당 메소드/클래스/패키지의 모든 오류를 처리 할 수 ​​있습니다. 트릭은 KeyGenerator이 메소드 이전에 인터셉터를 사용하여 호출되었으므로이를 수신하기 위해 해당 KeyGenerator 클래스에 애스펙트를 넣어야합니다.

이 작업 예제를 참조하십시오 : https://gist.github.com/gokhanoner/026c2b90fe3a61b93626383a61932395

참고 : 나는 캐시 제공자 측에서 예외를 throw 테스트하지 않았다, 당신은 아마 그 부분뿐만 아니라 CacheErrorHandler를 정의 할 필요가있다.

+0

스프링 박사님은 MVC의 오류와 캐시 공급자의 오류를 처리하는 데 큰 의미가 있다고 말씀하셨습니다. 당신이 참조한 github 예제는 실행되지 않았지만 코드 생성시 keyGeneration 동안, 즉 generate() 함수 내에서 Service 레이어에서 RuntimeException을 던져 버렸습니다. 그래서 내가 직면하고있는 문제를 해결하지 못했습니다. 내 경우에는 어떤 이유로 든 제공된 매개 변수가 유효하지 않고 캐시 키를 생성하는 데 사용할 수없는 경우 RuntimeException을 던집니다. 나는 당신의 제안을 Aspect를 사용하여 처리하려고 시도 하겠지만, 예외를 처리하고, 서비스 API에서 로그하고 계속 진행하기에 충분하지 않을지 다시 확신하지는 못한다. – NRA

+0

@NRA, 나는 실행중인 예제를 복사했습니다. 원한다면 프로젝트를 공유 할 수 있습니다. 예제를 실행하면 예외가 발생합니다. 생성 된 Aspect에 의해 캡처됩니다. –

+0

2017-12-22 13 : 58 : 56.625 ERROR 1896 --- [main] cecachetest.AfterThrowingExample : Object org에 대한 오류 처리 .springframework.cache.interceptor.KeyGenerator.generate (Object, Method, Object []). 인수 : [[email protected], public java.lang.String com.example.cachetest.DummyService.get (java.lang.Integer), [Ljava.lang.Object], @ 63dd899] java. 랭.ArrayIndexOutOfBoundsException : 1 at com.example.cachetest.CustomKeyGenerator.generate (CacheTestApplication.java:66) ~ [classes/: na] –