Spring redisson usage example

spring redisson usage example

Goal

  1. Try to avoid reinventing the wheel
  2. Keep data compatible with spring data
  3. Configuration information uses spring’s general configuration mechanism

redisson spring starter
Redisson provides support for spring, url address: https://github.com/redisson/redisson/tree/master/redisson-spring-boot-starter#spring-boot-starter. This starter provides the following spring beans:

  • RedissonClient
  • RedissonRxClient
  • RedissonReactiveClient
  • RedisTemlate
  • ReactiveRedisTemplate

pom file

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

Introducing this starter, you can use redis in the way of redisson, or you can use redis in the way of RedisTemplate in spring-boot-starter-data-redis.

Serialization/Deserialization
Both redisson-spring-boot-starter and spring-boot-starter-data-redis provide RedisTemplate and StringRedisTemplate.
But in most scenarios, the key in redis is String, and the value is Object, so add a bean of type RedisTemplate.
By default, the serialization/deserialization methods of redisson and redisTemplate are different, so that the data written by different redis clients can only be read by their own clients, and even in redis-cli, they cannot be maintained manually.
Therefore, the value needs to be saved in json format, and the serialization/deserialization of json format is implemented by jackson.

The advantage of using RedisTemplate is that RedisTemplate has provided us with the deserialization cache as the correct bean, and there is no need to manually convert String to bean again.
Can be used like this: WarehouseInfo warehouseJson = (WarehouseInfo)redisTemplate.opsForValue().get(“redisson:redis:warehouse:json”);

The json serialization of redisson is implemented by configuring the encoding method. Set encoding to org.redisson.codec.JsonJacksonCodec. RedisTemplate needs to add bean definition and configure serialization/deserialization configuration.

@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);
      // Specify the domain to be serialized, field, get and set, and modifier range, ANY includes private and public
      om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
      // The purpose of calling this method is that the generated json includes the class name, DefaultTyping.EVERYTHING means: all types (including reference types, native types) class information will be written into json
      // JsonTypeInfo.As.PROPERTY: will contain the @class property as a property of serialization, and the value is the fully qualified name type.
      // {"@class":"com.haole.redissionspring.dto.WarehouseInfo","warehouseId":["java.lang.Long",100000000],"warehouseName": "Qingdao Central Warehouse"}
      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;
  }

In this way, redisson and redisTemplate data are compatible, and can also be maintained manually in redis-cli.

Depending on the configuration, there are multiple json formats. If there is a json that cannot be processed by redisson or RedisTemplate, you can use StringRedisTemplate to get the cache in String format and analyze it manually.
—————

configuration file

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

The content of redisson.yml is a sample of redis cluster mode

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"

Among them, codec specifies the encoding method of json format. The configuration method of redisson using files cannot use the configuration center of spring cloud, because from the source code point of view, it reads files from the local project. For this situation, the config method can be used, but the config method also has a problem, because the entire config is a string.

RedisTemplate uses

// string cache
redisTemplate.opsForValue().set("redisson:redis:string", "test string new");
// bean cache
WarehouseInfo warehouse = new WarehouseInfo();
        warehouse.setWarehouseId(100000000L);
        warehouse.setWarehouseName("Qingdao Central Warehouse");
redisTemplate.opsForValue().set("redisson:redis:warehouse", warehouse);
 

RedissonClient uses

// string cache
RBucket<String> bucket = redissonClient.getBucket("redisson:redisson:string");
bucket.set("redisson string");
 
// bean cache
WarehouseInfo warehouse = new WarehouseInfo();
warehouse.setWarehouseId(100000079L);
warehouse.setWarehouseName("Luoyang Central Warehouse");
RBucket<WarehouseInfo> bucket1 = redissonClient.getBucket("redisson:redisson:warehouse");
bucket1.set(warehouse);
 
// get redisTemplate written in the cache
RBucket<WarehouseInfo> bucket2 = redissonClient.getBucket("redisson:redis:warehouse");
WarehouseInfo warehouseInfo = bucket2. get();

Use across projects
Using the above encoding method, if the cache is only used in one project, there is only one kind of serialization/deserialization, no matter which method is used, there is no problem. However, if the same cache is used across different projects,
The serialization/deserialization method needs to be the same, and the full class name must also be the same, but this is difficult to do. One way to solve this problem is to use org.redisson.client.codec.StringCodec for encoding.
Manually serialize to json before writing to the cache, and manually deserialize json after reading the cache. This way StringRedisTemplate can also be used.