Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 基于Spring引导的REST服务,使用hazelcast的Spring缓存无法处理缓存错误_Java_Spring_Caching_Spring Boot_Hazelcast - Fatal编程技术网

Java 基于Spring引导的REST服务,使用hazelcast的Spring缓存无法处理缓存错误

Java 基于Spring引导的REST服务,使用hazelcast的Spring缓存无法处理缓存错误,java,spring,caching,spring-boot,hazelcast,Java,Spring,Caching,Spring Boot,Hazelcast,我正在使用SpringBoot和hazelcast作为我的REST服务进行缓存 我正在使用带有自定义密钥生成器的spring@cacable注释在服务层(API)进行缓存。除了从自定义键生成器函数中抛出RuntimeException外,其他一切都可以正常工作,它不是由我添加到处理错误场景中的自定义错误类处理的 扩展org.springframework.cache.annotation.CachingConfigurerSupport的自定义错误类(CacheErrorHandler)覆盖所有

我正在使用SpringBoot和hazelcast作为我的REST服务进行缓存

我正在使用带有自定义密钥生成器的spring@cacable注释在服务层(API)进行缓存。除了从自定义键生成器函数中抛出RuntimeException外,其他一切都可以正常工作,它不是由我添加到处理错误场景中的自定义错误类处理的

扩展org.springframework.cache.annotation.CachingConfigurerSupport的自定义错误类(CacheErrorHandler)覆盖所有处理获取、放置和逐出错误的方法

在我的例子中,如果自定义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根据SpringDoc的说法,
CacheErrorHandler
只使用缓存提供程序抛出的异常,而不使用其他异常。不适用于键生成器,甚至不适用于注释方法引发的异常

请参阅:

对于MVC控制器,Spring有一个注释来帮助您处理错误:
@ErrorHandler
。您可以在此处找到更多详细信息:

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

请参见此工作示例:


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

您提到的Spring文档对于处理MVC的错误和缓存提供程序的错误很有意义。您提到的github示例没有运行,但从代码上看,它在服务层抛出RuntimeException,而不是在keyGeneration期间,即在by generate()函数中,因此它没有解决我面临的问题。在我的例子中,如果由于任何原因提供的参数无效并且不能用于创建缓存密钥,则引发RuntimeException。我将尝试您的建议,使用Aspect来处理它,但仍然不确定这是否足以在服务api中处理异常、记录并继续。@NRA,我复制了一个正在运行的示例。如果你愿意,我可以分享这个项目。如果您运行该示例,这就是您得到的异常,由我创建的方面捕获:2017-12-22 13:58:56.625错误1896---[main]c.e.cachetest.afterhowingExample:handle ERROR for Object org.springframework.cache.interceptor.KeyGenerator.generate(Object,Method,Object[])。参数:[com.example.cachetest。DummyService@663411de,public java.lang.String com.example.cachetest.DummyService.get(java.lang.Integer),[Ljava.lang.Object;@63dd899]java.lang.ArrayIndexOutOfBoundsException:1位于com.example.cachetest.CustomKeyGenerator.generate(CacheTestApplication.java:66)~[classes/:na]我明白你的意思了,使用AOP,如你的示例所示,你可以捕获错误并记录日志,但在我的例子中,这不会有帮助,因为函数在KeyGenerator期间抛出RuntimeException,即使我按照你的建议应用AOP,它也会继续,并最终导致未经处理的应用程序崩溃,而不是继续应用程序的其余功能ty(意思是如果缓存失败应用程序不应该)。例如,使用下面的代码并查看公共对象生成(对象o、方法方法、对象…参数){throw new RuntimeException(“11”);}在做了更多的调查之后,似乎需要处理来自自定义KeyGenerator(对象/函数)的异常不是正确的方式/实现。虽然处理异常应该是可能的,但似乎没有必要,因为spring本身的默认keyGenerator通过在对象数组中包装null对象并将值1赋值为hashcode来处理异常。有关更多详细信息,请查看签出代码org.springframework.cache.interceptor.SimpleKeyGenerator我仍然想知道一种优雅的方式来处理定制keyGenerator的这个用例。