Spring @Cacheable redis异常不影响正常业务方案

 更新时间:2021年02月19日 08:36:58   作者:神农L  
这篇文章主要介绍了Spring @Cacheable redis异常不影响正常业务方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

背景

项目中,使用@Cacheable进行数据缓存。发现:当redis宕机之后,@Cacheable注解的方法并未进行缓存冲突,而是直接抛出异常。而这样的异常会导致服务不可用。

原因分析

我们是通过@EnableCaching进行缓存启用的,因此可以先看@EnableCaching的相关注释

通过@EnableCaching的类注释可发现,spring cache的核心配置接口为:org.springframework.cache.annotation.CachingConfigurer

/**
 * Interface to be implemented by @{@link org.springframework.context.annotation.Configuration
 * Configuration} classes annotated with @{@link EnableCaching} that wish or need to
 * specify explicitly how caches are resolved and how keys are generated for annotation-driven
 * cache management. Consider extending {@link CachingConfigurerSupport}, which provides a
 * stub implementation of all interface methods.
 *
 * <p>See @{@link EnableCaching} for general examples and context; see
 * {@link #cacheManager()}, {@link #cacheResolver()} and {@link #keyGenerator()}
 * for detailed instructions.
 *
 * @author Chris Beams
 * @author Stephane Nicoll
 * @since 3.1
 * @see EnableCaching
 * @see CachingConfigurerSupport
 */
public interface CachingConfigurer {

 /**
 * Return the cache manager bean to use for annotation-driven cache
 * management. A default {@link CacheResolver} will be initialized
 * behind the scenes with this cache manager. For more fine-grained
 * management of the cache resolution, consider setting the
 * {@link CacheResolver} directly.
 * <p>Implementations must explicitly declare
 * {@link org.springframework.context.annotation.Bean @Bean}, e.g.
 * <pre class="code">
 * Configuration
 * EnableCaching
 * public class AppConfig extends CachingConfigurerSupport {
 *  Bean // important!
 *  Override
 *  public CacheManager cacheManager() {
 *   // configure and return CacheManager instance
 *  }
 *  // ...
 * }
 * </pre>
 * See @{@link EnableCaching} for more complete examples.
 */
 CacheManager cacheManager();

 /**
 * Return the {@link CacheResolver} bean to use to resolve regular caches for
 * annotation-driven cache management. This is an alternative and more powerful
 * option of specifying the {@link CacheManager} to use.
 * <p>If both a {@link #cacheManager()} and {@code #cacheResolver()} are set,
 * the cache manager is ignored.
 * <p>Implementations must explicitly declare
 * {@link org.springframework.context.annotation.Bean @Bean}, e.g.
 * <pre class="code">
 * Configuration
 * EnableCaching
 * public class AppConfig extends CachingConfigurerSupport {
 *  Bean // important!
 *  Override
 *  public CacheResolver cacheResolver() {
 *   // configure and return CacheResolver instance
 *  }
 *  // ...
 * }
 * </pre>
 * See {@link EnableCaching} for more complete examples.
 */
 CacheResolver cacheResolver();

 /**
 * Return the key generator bean to use for annotation-driven cache management.
 * Implementations must explicitly declare
 * {@link org.springframework.context.annotation.Bean @Bean}, e.g.
 * <pre class="code">
 * Configuration
 * EnableCaching
 * public class AppConfig extends CachingConfigurerSupport {
 *  Bean // important!
 *  Override
 *  public KeyGenerator keyGenerator() {
 *   // configure and return KeyGenerator instance
 *  }
 *  // ...
 * }
 * </pre>
 * See @{@link EnableCaching} for more complete examples.
 */
 KeyGenerator keyGenerator();

 /**
 * Return the {@link CacheErrorHandler} to use to handle cache-related errors.
 * <p>By default,{@link org.springframework.cache.interceptor.SimpleCacheErrorHandler}
 * is used and simply throws the exception back at the client.
 * <p>Implementations must explicitly declare
 * {@link org.springframework.context.annotation.Bean @Bean}, e.g.
 * <pre class="code">
 * Configuration
 * EnableCaching
 * public class AppConfig extends CachingConfigurerSupport {
 *  Bean // important!
 *  Override
 *  public CacheErrorHandler errorHandler() {
 *   // configure and return CacheErrorHandler instance
 *  }
 *  // ...
 * }
 * </pre>
 * See @{@link EnableCaching} for more complete examples.
 */
 CacheErrorHandler errorHandler();

}

该接口errorHandler方法可配置异常的处理方式。通过该方法上的注释可以发现,默认的CacheErrorHandler实现类是org.springframework.cache.interceptor.SimpleCacheErrorHandler

/**
 * A simple {@link CacheErrorHandler} that does not handle the
 * exception at all, simply throwing it back at the client.
 *
 * @author Stephane Nicoll
 * @since 4.1
 */
public class SimpleCacheErrorHandler implements CacheErrorHandler {

 @Override
 public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
 throw exception;
 }

 @Override
 public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
 throw exception;
 }

 @Override
 public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
 throw exception;
 }

 @Override
 public void handleCacheClearError(RuntimeException exception, Cache cache) {
 throw exception;
 }
}

SimpleCacheErrorHandler类注释上说明的很清楚:对cache的异常不做任何处理,直接将该异常抛给客户端。因此默认的情况下,redis服务器异常后,直接就阻断了正常业务

解决方案

通过上面的分析可知,我们可以通过自定义CacheErrorHandler来干预@Cacheable的异常处理逻辑。具体代码如下:

public class RedisConfig extends CachingConfigurerSupport {

  /**
   * redis数据操作异常处理。该方法处理逻辑:在日志中打印出错误信息,但是放行。
   * 保证redis服务器出现连接等问题的时候不影响程序的正常运行
   */
  @Override
  public CacheErrorHandler errorHandler() {
    return new CacheErrorHandler() {
      @Override
      public void handleCachePutError(RuntimeException exception, Cache cache,
                      Object key, Object value) {
        handleRedisErrorException(exception, key);
      }

      @Override
      public void handleCacheGetError(RuntimeException exception, Cache cache,
                      Object key) {
        handleRedisErrorException(exception, key);
      }

      @Override
      public void handleCacheEvictError(RuntimeException exception, Cache cache,
                       Object key) {
        handleRedisErrorException(exception, key);
      }

      @Override
      public void handleCacheClearError(RuntimeException exception, Cache cache) {
        handleRedisErrorException(exception, null);
      }
    };
  }

  protected void handleRedisErrorException(RuntimeException exception, Object key) {
    log.error("redis异常:key=[{}]", key, exception);
  }
}

到此这篇关于Spring @Cacheable redis异常不影响正常业务方案的文章就介绍到这了,更多相关Spring @Cacheable redis异常内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈Java设置PPT幻灯片背景——纯色、渐变、图片背景

    浅谈Java设置PPT幻灯片背景——纯色、渐变、图片背景

    这篇文章主要介绍了Java设置PPT幻灯片背景——纯色、渐变、图片背景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • 详解Java修饰符

    详解Java修饰符

    Java语言提供了很多修饰符,主要分为以下两类:访问修饰符;非访问修饰符。修饰符用来定义类、方法或者变量,通常放在语句的最前端。我们通过下面的例子来说明,下面就跟小编一起来看下吧
    2016-12-12
  • 关于eclipse安装spring插件报错An error occurred while collecting items to be installed...解决方案

    关于eclipse安装spring插件报错An error occurred while collecting item

    这篇文章主要介绍了关于eclipse安装spring插件报错An error occurred while collecting items to be installed...解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java根据日期计算星期几的四种方法

    Java根据日期计算星期几的四种方法

    在我们日常业务代码中,经常要用到星期几,下面这篇文章主要给大家介绍了关于Java根据日期计算星期几的四种方法,文中通过代码将每种实现的非常详细,需要的朋友可以参考下
    2023-09-09
  • Mybatis查询Sql结果未映射到对应得实体类上的问题解决

    Mybatis查询Sql结果未映射到对应得实体类上的问题解决

    使用mybatis查询表数据得时候,发现对应得实体类字段好多都是null,本文主要介绍了Mybatis查询Sql结果未映射到对应得实体类上的问题解决,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • Java项目如何防止SQL注入(多种方案汇总)

    Java项目如何防止SQL注入(多种方案汇总)

    SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,这篇文章主要介绍了 Java项目防止SQL注入的四种方案,需要的朋友可以参考下
    2023-12-12
  • 使用Java自定义注解实现一个简单的令牌桶限流器

    使用Java自定义注解实现一个简单的令牌桶限流器

    限流是在分布式系统中常用的一种策略,它可以有效地控制系统的访问流量,保证系统的稳定性和可靠性,在本文中,我将介绍如何使用Java自定义注解来实现一个简单的令牌桶限流器,需要的朋友可以参考下
    2023-10-10
  • Java中在控制台读取字符的实现示例

    Java中在控制台读取字符的实现示例

    Scanner是Java中的一个类,可以用于读取控制台输入,通过Scanner对象可以方便地从控制台读取数字或字符串,本文就来介绍一下Java中在控制台读取字符的实现示例,感兴趣的可以了解一下
    2023-10-10
  • Java将json对象转换为map键值对案例详解

    Java将json对象转换为map键值对案例详解

    这篇文章主要介绍了Java将json对象转换为map键值对案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • MyBatis逆向工程生成dao层增删改查的操作

    MyBatis逆向工程生成dao层增删改查的操作

    这篇文章主要介绍了MyBatis逆向工程生成dao层增删改查的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08

最新评论