使用spring cache时,出现缓存无连接的处理方法

描述:

  • 当使用spring cache的注释@cacheable,@cacheput等语法处理缓存问题时,很容易会出现如果缓存数据库出现问题,宕机的情况导致关闭。一般而言这时候我们希望将无法连接的异常捕获显示,然后再继续连接数据库。但是我们使用的注解语言无法catch exception,所以最后导致的结果是直接导致整个服务器报错无法正常工作。

解决方法(spring boot中)

创建一个继承redisCacheManager的自定义类。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.util.Assert;

import java.util.concurrent.Callable;

class CustomRedisCacheManager extends RedisCacheManager {
    private static Logger logger = LoggerFactory.getLogger(CustomRedisCacheManager.class);

    public CustomRedisCacheManager(RedisOperations redisOperations) {
        super(redisOperations);
    }

    @Override
    public Cache getCache(String name) {
        return new RedisCacheWrapper(super.getCache(name));
    }


    protected static class RedisCacheWrapper implements Cache {

        private final Cache delegate;

        public RedisCacheWrapper(Cache redisCache) {
            Assert.notNull(redisCache, "delegate cache must not be null");
            this.delegate = redisCache;
        }

        @Override
        public String getName() {
            try {
                return delegate.getName();
            } catch (Exception e) {
                return handleException(e);
            }
        }

        @Override
        public Object getNativeCache() {
            try {
                return delegate.getNativeCache();
            } catch (Exception e) {
                return handleException(e);
            }
        }

        @Override
        public Cache.ValueWrapper get(Object key) {
            try {
                return delegate.get(key);
            } catch (Exception e) {
                return handleException(e);
            }
        }

        @Override
        public  T get(Object o, Class aClass) {
            try {
                return delegate.get(o, aClass);
            } catch (Exception e) {
                return handleException(e);
            }
        }

        @Override
        public  T get(Object o, Callable callable) {
            try {
                return delegate.get(o, callable);
            } catch (Exception e) {
                return handleException(e);
            }
        }

        @Override
        public void put(Object key, Object value) {
            try {
                delegate.put(key, value);
            } catch (Exception e) {
                handleException(e);
            }
        }

        @Override
        public ValueWrapper putIfAbsent(Object o, Object o1) {
            try {
                return delegate.putIfAbsent(o, o1);
            } catch (Exception e) {
                return handleException(e);
            }
        }

        @Override
        public void evict(Object o) {
            try {
                delegate.evict(o);
            } catch (Exception e) {
                handleException(e);
            }
        }

        @Override
        public void clear() {
            try {
                delegate.clear();
            } catch (Exception e) {
                handleException(e);
            }
        }

        private  T handleException(Exception e) {
            logger.error("handleException", e);
            return null;
        }
    }
}

然后在configuration应用这个自定义的redisCacheManager.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
public class RedisConfig {
    @Bean
    public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
        CustomRedisCacheManager redisCacheManager = new CustomRedisCacheManager(redisTemplate);
        redisCacheManager.setUsePrefix(true);
        return redisCacheManager;
    }
}

感谢https://stackoverflow.com/questions/29003786/how-to-disable-redis-caching-at-run-time-if-redis-connection-failed中@John Blum的回答
---end---

你可能感兴趣的:(使用spring cache时,出现缓存无连接的处理方法)