3 Springboot中使用redis,redis自动缓存异常处理

来源:互联网 发布:怎么在手机上装修淘宝 编辑:程序博客网 时间:2024/06/14 10:30

在上一篇中,提到了使用配置文件来定义连接信息,由于前面讲的都是框架自动使用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. */@Configurationpublic 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的其他使用方法。


1 0
原创粉丝点击