转载请注明出处:https://blog.csdn.net/l1028386804/article/details/82597154
使用Cacheable注解Redis方法时,如果Redis服务器挂了,就直接抛出异常了,
java.net.ConnectException: Connection refused: connect
那么,有没有什么办法可以继续向下执行方法,从相关的数据库中查询数据,而不是直接抛出异常导致整个程序终止运行呢?
经过反复翻看Spring的源码和相关资料,并经过不断验证,得出了答案:有相关的方案!!!
解决方案就是重写CachingConfigurerSupport中的四个方法:
package org.springframework.cache.annotation;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.interceptor.KeyGenerator;
/**
* An implementation of {@link CachingConfigurer} with empty methods allowing
* sub-classes to override only the methods they're interested in.
*
* @author Stephane Nicoll
* @since 4.1
* @see CachingConfigurer
*/
public class CachingConfigurerSupport implements CachingConfigurer {
@Override
public CacheManager cacheManager() {
return null;
}
@Override
public KeyGenerator keyGenerator() {
return null;
}
@Override
public CacheResolver cacheResolver() {
return null;
}
@Override
public CacheErrorHandler errorHandler() {
return null;
}
}
具体如下:
1、BaseRedisConfig类
package io.mykit.cache.redis.spring.annotation.config;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
/**
* @author liuyazhuang
* @version 1.0.0
* @date 2018/8/21 18:48
* @description Redis集群配置基础类
*/
@Data
public class BaseRedisConfig extends CachingConfigurerSupport {
@Value("${redis.cluster.max.total}")
protected Integer maxTotal;
@Value("${redis.cluster.max.idle}")
protected Integer maxIdle;
@Value("${redis.cluster.min.idle}")
protected Integer minIdle;
@Value("${redis.cluster.timeout}")
protected Integer timeout;
@Value("${redis.cluster.maxAttempts}")
protected Integer maxAttempts;
@Value("${redis.cluster.redisDefaultExpiration}")
protected Integer redisDefaultExpiration;
@Value("${redis.cluster.usePrefix}")
protected Boolean usePrefix;
@Value("${redis.cluster.blockWhenExhausted}")
protected Boolean blockWhenExhausted;
@Value("${redis.cluster.maxWaitMillis}")
protected Integer maxWaitMillis;
@Value("${redis.cluster.testOnBorrow}")
protected Boolean testOnBorrow;
@Value("${redis.cluster.testOnReturn}")
protected Boolean testOnReturn;
@Value("${redis.cluster.testWhileIdle}")
protected Boolean testWhileIdle;
@Value("${redis.cluster.minEvictableIdleTimeMillis}")
protected Integer minEvictableIdleTimeMillis;
@Value("${redis.cluster.timeBetweenEvictionRunsMillis}")
protected Integer timeBetweenEvictionRunsMillis;
@Value("${redis.cluster.numTestsPerEvictionRun}")
protected Integer numTestsPerEvictionRun;
@Value("${redis.cluster.password}")
protected String password;
@Value("${redis.cluster.defaultExpirationKey}")
protected String defaultExpirationKey;
@Value("${redis.cluster.expirationSecondTime}")
protected Integer expirationSecondTime;
@Value("${redis.cluster.preloadSecondTime}")
protected Integer preloadSecondTime;
@Value("${redis.cluster.index.zero}")
protected Integer zero;
@Value("${redis.cluster.index.one}")
protected Integer one;
@Value("${redis.cluster.index.two}")
protected Integer two;
@Value("${redis.cluster.index.three}")
protected Integer three;
@Value("${redis.cluster.node.one}")
protected String nodeOne;
@Value("${redis.cluster.node.one.port}")
protected Integer nodeOnePort;
@Value("${redis.cluster.node.two}")
protected String nodeTwo;
@Value("${redis.cluster.node.two.port}")
protected Integer nodeTwoPort;
@Value("${redis.cluster.node.three}")
protected String nodeThree;
@Value("${redis.cluster.node.three.port}")
protected Integer nodeThreePort;
@Value("${redis.cluster.node.four}")
protected String nodeFour;
@Value("${redis.cluster.node.four.port}")
protected Integer nodeFourPort;
@Value("${redis.cluster.node.five}")
protected String nodeFive;
@Value("${redis.cluster.node.five.port}")
protected Integer nodeFivePort;
@Value("${redis.cluster.node.six}")
protected String nodeSix;
@Value("${redis.cluster.node.six.port}")
protected Integer nodeSixPort;
@Value("${redis.cluster.node.seven}")
protected String nodeSeven;
@Value("${redis.cluster.node.seven.port}")
protected Integer nodeSevenPort;
@Override
public String toString(){
return JSONObject.toJSONString(this);
}
}
2、CacheRedisConfig类
package io.mykit.cache.redis.spring.annotation.config;
import com.alibaba.fastjson.parser.ParserConfig;
import io.mykit.cache.redis.spring.aspect.CachingAnnotationsAspect;
import io.mykit.cache.redis.spring.cache.CacheKeyGenerator;
import io.mykit.cache.redis.spring.cache.CacheTime;
import io.mykit.cache.redis.spring.cache.CustomizedRedisCacheManager;
import io.mykit.cache.redis.spring.serializer.FastJsonRedisSerializer;
import io.mykit.cache.redis.spring.serializer.StringRedisSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author liuyazhuang
* @version 1.0.0
* @date 2018/8/21 19:06
* @description Redis配置类
*/
@Slf4j
public class CacheRedisConfig extends BaseRedisConfig{
/**
* 配置 JedisPoolConfig
* @return JedisPoolConfig对象
*/
@Bean
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxTotal);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
jedisPoolConfig.setTestOnReturn(testOnReturn);
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
return jedisPoolConfig;
}
/**
* 配置 RedisClusterConfiguration
* @return RedisClusterConfiguration对象
*/
@Bean
public RedisClusterConfiguration redisClusterConfiguration(){
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
redisClusterConfiguration.setMaxRedirects(3);
redisClusterConfiguration.setClusterNodes(getRedisNodes());
return redisClusterConfiguration;
}
/**
* 配置 JedisConnectionFactory
* @return 返回JedisConnectionFactory对象
*/
@Bean
public JedisConnectionFactory jedisConnectionFactory(){
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisClusterConfiguration(), jedisPoolConfig());
jedisConnectionFactory.setPassword(password);
jedisConnectionFactory.setTimeout(timeout);
return jedisConnectionFactory;
}
/**
* 配置RedisTemplate
* @return RedisTemplate对象
*/
@Bean
public RedisTemplate redisTemplate(){
RedisTemplate redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
StringRedisSerializer keySerializer = new StringRedisSerializer();
FastJsonRedisSerializer
问题解决。