spring redisson usage example
Goal
- Try to avoid reinventing the wheel
- Keep data compatible with spring data
- 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.