spring cache redis缓存断熔实现

最近项目需要增加缓存功能,由于dao层使用的mybatis,一开始考虑使用mybatis的二级缓存来实现,但是发现针对多表联合的情况下不好实现,所以转战spring cache + redis。

1、增加maven配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

 

2、定义cache config

@Configuration
@Slf4j
public class CacheManageConfig<K,V> {

    @Bean
    public CacheManager cacheManager(RedisTemplate<K,V> redisTemplate) {
        log.info("--------------------  cacheManager init ---------------------");
        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);

        RedisCacheManager cacheManager = new CustomRedisCacheManager(redisTemplate);
        cacheManager.setDefaultExpiration(300);
        return cacheManager;
    }

}

 

@Slf4j
public class CustomRedisCacheManager extends RedisCacheManager{

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

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

}

 

@Slf4j
public class RedisCacheWrapper implements Cache {

    private final Cache delegate;

    public RedisCacheWrapper(Cache redisCache) {
        this.delegate = redisCache;
    }

    @Override
    public String getName() {
        try {
            return delegate.getName();
        } catch (Exception e) {
            log.warn("redis异常,缓存功能失效...");
            return null;
        }
    }

    @Override
    public Object getNativeCache() {
        try {
            return delegate.getNativeCache();
        } catch (Exception e) {
            log.warn("redis异常,缓存功能失效...");
            return null;
        }
    }

    @Override
    public Cache.ValueWrapper get(Object key) {
        try {
            return delegate.get(key);
        } catch (Exception e) {
            log.warn("redis异常,缓存功能失效...");
            return null;
        }
    }

    @Override
    public <T> T get(Object o, Class<T> aClass) {
        try {
            return delegate.get(o, aClass);
        } catch (Exception e) {
            log.warn("@Cacheable异常,缓存功能失效...");
            return null;
        }
    }

    @Override
    public <T> T get(Object o, Callable<T> callable) {
        try {
            return delegate.get(o, callable);
        } catch (Exception e) {
            try{
                log.warn("@Cacheable异常,缓存功能失效...");
                return callable.call();
            } catch (Exception e1) {
                return null;
            }
        }
    }

    @Override
    public void put(Object key, Object value) {
        try {
            delegate.put(key, value);
        } catch (Exception e) {
            log.warn("@CachePut异常,缓存功能失效...");
        }
    }

    @Override
    public ValueWrapper putIfAbsent(Object o, Object o1) {
        try {
            return delegate.putIfAbsent(o, o1);
        } catch (Exception e) {
            log.warn("@CachePut异常,缓存功能失效...");
            return null;
        }
    }

    @Override
    public void evict(Object o) {
        try {
            delegate.evict(o);
        } catch (Exception e) {
            log.warn("@CacheEvict异常,缓存功能失效...");
        }
    }

    @Override
    public void clear() {
        try {
            delegate.clear();
        } catch (Exception e) {
            log.warn("redis异常,缓存功能失效...");
        }
    }
}

 

3、使用方式直接沿用spring cache

@Cacheable(key = "'OTN-'+#resID",value = "OTNCache",sync = true)
@CacheEvict(key = "'OTN-'+#resID",value = "OTNCache",beforeInvocation = true)

服务启动后,如何redis没有做缓存且宕机的话,通过RedisCacheWapper就能捕获redis的connection error错误

比如@Cacheable,

当宕机后调用

@Override
public <T> T get(Object o, Callable<T> callable) {
    try {
        return delegate.get(o, callable);
    } catch (Exception e) {
        try{
            log.warn("@Cacheable异常,缓存功能失效...");
            return callable.call();
        } catch (Exception e1) {
            return null;
        }
    }
}

捕获redis连接异常,执行service层真实逻辑callable.call()

 

转载于:https://my.oschina.net/u/1992831/blog/2249254

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值