spring redisson 使用样例

spring redisson 使用样例

目标

  1. 尽量避免重复造轮子
  2. 与spring data保持数据兼容
  3. 配置信息使用spring通用的配置机制

 redisson spring starter
 redisson提供了对spring的支持,url地址:https://github.com/redisson/redisson/tree/master/redisson-spring-boot-starter#spring-boot-starter 。此starter提供下列spring bean:

  • RedissonClient
  • RedissonRxClient
  • RedissonReactiveClient
  • RedisTemlate
  • ReactiveRedisTemplate

pom文件

 <dependency>
      <groupId>org.redisson</groupId>
      <artifactId>redisson-spring-boot-starter</artifactId>
      <version>3.15.5</version>
      <exclusions>
          <exclusion>
              <groupId>org.redisson</groupId>
              <artifactId>redission-spring-data-24</artifactId>
          </exclusion>
      </exclusions>
  </dependency>
  <dependency>
      <groupId>org.redisson</groupId>
      <artifactId>redisson-spring-data-23</artifactId>
      <version>3.15.5</version>
  </dependency>

 引入此starter,可以使用redisson的方式使用redis,也可以使用spring-boot-starter-data-redis中RedisTemplate方式使用redis。

序列化/反序列化
无论是redisson-spring-boot-starter还是spring-boot-starter-data-redis,都提供了RedisTemplate和StringRedisTemplate。
但是多数场景下,redis中的key是String,value是Object,所以增加RedisTemplate类型的bean。
在默认情况下redisson和redisTemplate的序列化/反序列化方式不同,导致不同redis客户端写入的数据只能使用各自的客户端读取,甚至在redis-cli中也无法手工维护。
所以value需要保存为json格式,json格式的序列化/反序列化使用jackson实现。

使用RedisTemplate好处是,RedisTemplate已经提我们反序列化缓存为正确的bean,不需要手工再次把String转换为bean。
可以这样使用:WarehouseInfo warehouseJson = (WarehouseInfo)redisTemplate.opsForValue().get("redisson:redis:warehouse:json");

redisson的json序列化通过配置编码方式实现。把编码设置为org.redisson.codec.JsonJacksonCodec。RedisTemplate需要增加bean定义,并配置序列化/反序列化配置。

@Bean
  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
      StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
      Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(
              Object.class);
 
      ObjectMapper om = new ObjectMapper();
      om.setSerializationInclusion(JsonInclude.Include.NON_NULL);
      om.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
      // 指定要序列化的域,field、get和set,以及修饰符范围,ANY包括private和public
      om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
      // 调用此方法的用途是生成的json包括类名,DefaultTyping.EVERYTHING的意思是:所有的类型(包括引用类型、原生类型)类信息都会写入json中
      // JsonTypeInfo.As.PROPERTY:将包含@class属性,作为序列化的一个属性,值就是完全限定名类型。
      // {"@class":"com.haole.redissionspring.dto.WarehouseInfo","warehouseId":["java.lang.Long",100000000],"warehouseName":"青岛中心仓"}
      om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.EVERYTHING,
              JsonTypeInfo.As.PROPERTY);
      jackson2JsonRedisSerializer.setObjectMapper(om);
 
      RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
      redisTemplate.setConnectionFactory(redisConnectionFactory);
      redisTemplate.setKeySerializer(stringRedisSerializer);
      redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
      redisTemplate.setHashKeySerializer(stringRedisSerializer);
      redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
      redisTemplate.afterPropertiesSet();
      return redisTemplate;
  }

这样就实现了redisson和redisTemplate数据兼容,并且在redis-cli中也可以手工维护。

根据配置不同,有多种json格式,如果出现redisson或者RedisTemplate无法处理的json,可以使用StringRedisTemplate,得到String格式的缓存,自己手工想法解析。
————————————————
 

 配置文件

  spring:
  application:
    name: redission-spring
  redis:
    redisson:
      file: classpath:redisson.yml

redisson.yml内容是redis集群模式的样例

clusterServersConfig:
    idleConnectionTimeout: 10000
    connectTimeout: 10000
    timeout: 3000
    retryAttempts: 3
    retryInterval: 1500
    failedSlaveReconnectionInterval: 3000
    failedSlaveCheckInterval: 60000
    password: null
    subscriptionsPerConnection: 5
    clientName: null
    loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> { }
    subscriptionConnectionMinimumIdleSize: 1
    subscriptionConnectionPoolSize: 50
    slaveConnectionMinimumIdleSize: 24
    slaveConnectionPoolSize: 64
    masterConnectionMinimumIdleSize: 32
    masterConnectionPoolSize: 64
    readMode: "SLAVE"
    subscriptionMode: "SLAVE"
    nodeAddresses:
    - "redis://127.0.0.1:6379"
    - "redis://127.0.0.1:6380"
    scanInterval: 1000
    pingConnectionInterval: 0
    keepAlive: false
    tcpNoDelay: false
  threads: 16
  nettyThreads: 32
  codec: !<org.redisson.codec.JsonJacksonCodec> { }
  transportMode: "NIO"

其中codec指定了json格式的编码方式。redisson这种使用文件的配置方式无法使用spring cloud的配置中心,因为从源码来看,是从工程的本地读取文件。针对这种情况,可以config方式,但是config方式也有一个问题,因为整个config是字符串。

RedisTemplate使用

// 字符串缓存
redisTemplate.opsForValue().set("redisson:redis:string", "test string new");
// bean缓存
WarehouseInfo warehouse = new WarehouseInfo();
        warehouse.setWarehouseId(100000000L);
        warehouse.setWarehouseName("青岛中心仓");
redisTemplate.opsForValue().set("redisson:redis:warehouse", warehouse);
 

 RedissonClient使用

// 字符串缓存
RBucket<String> bucket = redissonClient.getBucket("redisson:redisson:string");
bucket.set("redisson string");
 
// bean缓存
WarehouseInfo warehouse = new WarehouseInfo();
warehouse.setWarehouseId(100000079L);
warehouse.setWarehouseName("洛阳中心仓");
RBucket<WarehouseInfo> bucket1 = redissonClient.getBucket("redisson:redisson:warehouse");
bucket1.set(warehouse);
 
// get redisTemplate 写入在缓存
RBucket<WarehouseInfo> bucket2 = redissonClient.getBucket("redisson:redis:warehouse");
WarehouseInfo warehouseInfo = bucket2.get();

跨工程使用
采用上述编码方式,如果缓存只在一个工程内使用,序列化/反序列化只有一种,无论采用何种方式,都没有问题。但是,如果跨不同工程使用同一个缓存,
需要序列化/反序列化方式一样,并且也需要全类名也必须一样,但是这点很难做到。解决这个问题的一个思路,编码使用org.redisson.client.codec.StringCodec,
写入缓存之前先手工序列化为json,读取缓存后,手工反序列化json。这样也可以使用StringRedisTemplate
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值