java - 基于Spring boot的REST服务,带有hazelcast的spring缓存无法处理缓存错误

标签 java spring caching spring-boot hazelcast

我正在使用 Spring boot 和 hazelcast 作为 REST 服务的缓存。

我使用 spring @Cachable 注释和自定义 key 生成器在服务层(API)进行缓存。一切工作正常,除了当它从自定义 key 生成器函数抛出 RuntimeException 时,它不是由我添加来处理错误场景的自定义错误类处理的。

扩展 org.springframework.cache.annotation.CachingConfigurerSupport 的自定义错误类(CacheErrorHandler)覆盖所有处理 GET、PUT、EVICT 错误的方法。

在我的例子中,如果自定义的customKeyGenerator抛出RuntimeException,我希望它会闯入handleCacheGetError函数。

任何人都可以指出我在这里缺少的内容或帮助解释一下使用 spring 注释(即使用 @Cachable)处理缓存(如 HAZELCAST 或 REDIS 等)的缓存错误的正确方法。

作为示例,这是我的 API 缓存的样子

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

类似地,我的缓存配置类扩展了 CachingConfigurerSupport,如下所示

@Configuration
public class CacheConfiguration extends CachingConfigurerSupport {
...

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

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

最佳答案

@NRA,根据 Spring Doc,https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/interceptor/CacheErrorHandler.html , CacheErrorHandler 仅使用缓存提供程序抛出的异常,不使用其他任何东西。不适用于 key 生成器,甚至不适用于带注释的方法抛出的异常。

请参阅:https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheInvoker.java#L71

对于MVC Controller ,Spring有一个注解来帮助你处理错误:@ErrorHandler。您可以在这里找到更多详细信息:https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

如果不使用 MVC,您可以定义一个 Aspect Bean 并处理该方法/类/包的所有错误。诀窍是,在方法之前使用拦截器调用 KeyGenerator,因此您还需要向该 KeyGenerator 类添加一个方面来捕获它。

请参阅此工作示例:https://gist.github.com/gokhanoner/026c2b90fe3a61b93626383a61932395

注意:我没有测试从缓存提供程序端抛出异常,您很可能还需要为该部分定义 CacheErrorHandler

关于java - 基于Spring boot的REST服务,带有hazelcast的spring缓存无法处理缓存错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47916071/

相关文章:

java - Libgdx 数组 |删除全部导致错误

java - 空对象引用上的方法 'boolean java.lang.String.isEmpty()'

java - 为什么表单提交会打开新窗口/标签?

spring - 如何在 Spring 实体类中保留 ArrayList?

java - Spring 4 是否有 Maven 存储库?

java - Int 不能在 equals 方法中取消引用

java - AtomicBoolean 中 getAndSet 和 compareAndSet 的区别

android - 如何使用 Volley 从缓存中删除图像?

database - Cloud Firestore 是 CDN 的良好替代品吗?

caching - 何时在 GraphQL 服务器设置中使用 Redis 以及何时使用 DataLoader