3 Springboot中使用redis,redis自动缓存异常处理
时间:2022-06-17
本文章向大家介绍3 Springboot中使用redis,redis自动缓存异常处理,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
在上一篇中,提到了使用配置文件来定义连接信息,由于前面讲的都是框架自动使用redis缓存数据,那么如果出现了异常又该怎么处理?
这里我们修改一下配置信息,让redis故意连接不上,看看异常信息。
修改一下yml里port端口,然后再执行一下add或者query操作,看控制台报错信息。
打开AbstractCacheInvoker类,看到里面有put,get,evict等方法,就是对应在repository的注解,还有个无参的构造方法里初始化了一个SimpleCacheErrorHandler。
打开SimpleCacheErrorHandler类
这个类就是处理redis缓存异常的类,发现里面只是简单的在异常时throw Exception,这也导致了如果redis异常,那么程序就会抛出异常,像query时,如果redis异常,那程序就不再往下进行,也不再进行查数据库操作,其实这样是有风险的,我们希望redis异常后,db能继续响应客户端请求,然后记录这次异常,回头再处理。
处理redis异常,我们需要自定义CacheErrorHandler来替代默认的SimpleCacheErrorHandler。
打开之前的Redis配置类RedisCacheConfig,继承CachingConfigurerSupport,这个CachingConfigurerSupport就是供我们来自定义一些Cache相关配置的。
重写Override errorHandler方法:
package com.tianyalei.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
/**
* Created by wuwf on 17/4/24.
*/
@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.pool.min-idle}")
private int minIdle;
@Value("${spring.redis.pool.max-wait}")
private int maxWait;
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setPassword(password);
factory.setHostName(host);
factory.setPort(port);
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxActive);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setMaxWaitMillis(maxWait);
factory.setPoolConfig(jedisPoolConfig);
return factory;
}
@Bean
public RedisTemplate<String, String> getRedisTemplate() {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
//key序列化方式,但是如果方法上有Long等非String类型的话,会报类型转换错误
RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;
redisTemplate.setKeySerializer(redisSerializer);
// redisTemplate.setHashKeySerializer(redisSerializer);
// redisTemplate.setValueSerializer(redisSerializer);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
@Override
public CacheErrorHandler errorHandler() {
CacheErrorHandler cacheErrorHandler = new CacheErrorHandler() {
@Override
public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
System.out.println(key);
}
@Override
public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
System.out.println(value);
}
@Override
public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
}
@Override
public void handleCacheClearError(RuntimeException e, Cache cache) {
}
};
return cacheErrorHandler;
}
}
然后就可以在对应的方法上加自己的处理。
再试一下save或者get操作,发现系统已经不报错了,进入了我们自定义的errorHandler方法中。
下一篇继续探讨redis的其他使用方法。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- requests session的应用,python金点设计奖数据爬虫
- 站长工具关键词挖掘采集,Python关键词批量挖掘采集工具
- python百度关键词相关搜索词采集,链轮查询采集exe工具
- Python最火爬虫框架Scrapy入门与实践,豆瓣电影 Top 250 数据采集
- Python爬虫三种解析方式,Pyhton360搜索排名查询
- Python关键词百度指数采集,抓包Cookie及json数据处理
- 常用的package.json,还有这么多你不知道的骚技巧
- 【词库】Python关键词筛选分类,Levenshtein编辑距离算法分词
- 爬取数据缺失的补坑,Python数据爬取的坑坑洼洼如何铲平
- 如何开发跨框架的组件
- SpringBoot系列之异步任务@Async使用教程
- 深入k8s:k8s部署&在k8s中运行第一个程序
- Java是如何实现Future模式的?万字详解!
- Tensorflow基础入门十大操作总结
- Django个人博客,三小时带你入门Django框架