Java 基于Spring引导的REST服务,使用hazelcast的Spring缓存无法处理缓存错误
我正在使用SpringBoot和hazelcast作为我的REST服务进行缓存 我正在使用带有自定义密钥生成器的spring@cacable注释在服务层(API)进行缓存。除了从自定义键生成器函数中抛出RuntimeException外,其他一切都可以正常工作,它不是由我添加到处理错误场景中的自定义错误类处理的 扩展org.springframework.cache.annotation.CachingConfigurerSupport的自定义错误类(CacheErrorHandler)覆盖所有处理获取、放置和逐出错误的方法 在我的例子中,如果自定义customKeyGenerator抛出RuntimeException,我希望它会进入handleCacheGetError函数 任何人都可以告诉我这里缺少什么,或者帮助我解释一下使用spring注释(即使用@Cachable)处理缓存错误(如HAZELCAST或REDIS等)的正确方法 下面是我的API缓存的示例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)覆盖所有
@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的这个用例。