spring boot 基于注解式的缓存的配置redis

3 篇文章 0 订阅
2 篇文章 0 订阅

spring boot 基于注解式的缓存的配置redis

首先说说自己使用的Spring的版本是5.1.6.RELEASE,不同版本的配置会有所不一样

在网上找了一堆资料,关于redis的配置,基本上都是如下这种样子,我们首先来看看

代码如下



@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
        RedisCacheManager rm = new RedisCacheManager(redisTemplate);
        rm.setDefaultExpiration(30l);// 设置缓存时间
        return rm;
    }

    @Bean
    @Override
    public Object generate(Object target, Method method, Object... params) {
      StringBuilder sb = new StringBuilder();
      sb.append(target.getClass().getName());
      sb.append(method.getName());
      for (Object obj : params) {
          sb.append(obj.toString());
      }
      return sb.toString();
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        @SuppressWarnings({ "rawtypes", "unchecked" })
        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);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

但是这种方式在5.1.6中并不适用,
有如下几个问题:

  1. RedisCacheManager 并不能通过RedisTemplate来实例,

也就是说RedisCacheManager rm = new RedisCacheManager(redisTemplate);这一段代码是会报错的

没办法了,只有靠自己,一步步看源码来操作了
首先查看RedisCacheManager 的创建方式主要有三种,分别是通过RedisConnectionFactory,RedisCacheWriter,RedisCacheConfiguration或者这三者之间的组合方式来创建的,
并且有一些创建方式还是私有的,有兴趣的可以自己看源码了

我这里用了一个比较简单的方式 RedisConnectionFactory 来创建 RedisCacheManager,


     @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        return RedisCacheManager.create(factory);
    }
        

如果这样操作了,那就会引发第二个问题,我们序列化到redis中的数据,并不是json格式。
2. value 序列化方式

查看其它几种创建方式有没有能指定序列化方式的参数发现在RedisCacheConfiguration中有这样两个实例变量

    private final SerializationPair<String> keySerializationPair;
	private final SerializationPair<Object> valueSerializationPair;
    

很明显需要将序列化方式设置到RedisCacheConfiguration中并通过RedisCacheConfiguration这种方式来创建RedisCacheManager

最后将我自己的配置代码贴出来,供参考,需要注意的是,一下的代码会将部分的空数据也缓存起来,如果不需要可以在RedisCacheConfiguration中设为为不缓存空数据


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;

import java.time.Duration;
/**
 * @author John·Louis
 * <p>
 * Date: 2019/7.24
 * Description:
 *
 */
@Configuration
@EnableCaching
public class RedisConfiguration extends CachingConfigurerSupport {

    private static final String KEY_SEPARATE = "_";

    private static final int DURATION_TIME = 1 * 6;
    
    /**
    *这种方式是在手动指定RedisTemplate的时候会将value序列化为json格式存储到redis数据库,
    * 基于Spring Cacheable注解这种方式,序列化为json需要按照cacheManager中指定的方式
    *
    */
    @Bean("redisTemplate")
    public <String,T> RedisTemplate<String,T> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, T> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer<Object> 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);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setKeySerializer(stringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
    @Bean
    public StringRedisSerializer stringRedisSerializer() {
        return new StringRedisSerializer();
    }


    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration
                .defaultCacheConfig()
//                指定过期时间
                .entryTtl(Duration.ofHours(DURATION_TIME))
//                指定值value序列方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
        return RedisCacheManager.builder(factory)
                .cacheDefaults(cacheConfiguration)
                .build();
    }
    @Bean
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getSimpleName()).append(KEY_SEPARATE)
                    .append(method.getName());
            for (Object param : params) {
                sb.append(KEY_SEPARATE).append(param);
            }
            return sb.toString();
        };
    }
}


最后启动程序,在service上添加注解@Cacheable(cacheNames = "comment_cache",keyGenerator = "keyGenerator") 查询程序,
然后通过redis Desktop manager 来查看存储数据如下,
完美

{
    "@class": "com.louis.comment.entity.OrderComment",
    "id": 2,
    "orderId": 3,
    "commentUserId": 2,
    "commentTime": [
        "java.sql.Timestamp",
        1563975495000
    ],
    "updateTime": [
        "java.sql.Timestamp",
        1563975536000
    ],
    "goodsName": "first",
    "goodsId": 1,
    "sellerId": 99,
    "content": "this is the secount",
    "title": "first",
    "picPath": "string ",
    "new": false
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值