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文件

 
      org.redisson
      redisson-spring-boot-starter
      3.15.5
      
          
              org.redisson
              redission-spring-data-24
          
      
  
  
      org.redisson
      redisson-spring-data-23
      3.15.5
  

 引入此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 redisTemplate(RedisConnectionFactory redisConnectionFactory) {
      StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
      Jackson2JsonRedisSerializer 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 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: ! { }
    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: ! { }
  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 bucket = redissonClient.getBucket("redisson:redisson:string");
bucket.set("redisson string");
 
// bean缓存
WarehouseInfo warehouse = new WarehouseInfo();
warehouse.setWarehouseId(100000079L);
warehouse.setWarehouseName("洛阳中心仓");
RBucket bucket1 = redissonClient.getBucket("redisson:redisson:warehouse");
bucket1.set(warehouse);
 
// get redisTemplate 写入在缓存
RBucket bucket2 = redissonClient.getBucket("redisson:redis:warehouse");
WarehouseInfo warehouseInfo = bucket2.get();

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

你可能感兴趣的:(spring,spring,boot,java,redis)