Redisson是一款基于java开发的开源项目,提供了很多企业级实践,比如分布式锁、消息队列、异步执行等功能。本文基于Springboot2版本集成redisson-spring-boot-starter实现redisson的基本应用
软件环境:
-
JDK 1.8
-
SpringBoot 2.2.1
-
Maven 3.2+
-
Mysql 8.0.26
-
redisson-spring-boot-starter 3.15.6
-
开发工具
-
IntelliJ IDEA
-
smartGit
-
项目搭建:
快速新建一个Spring Initializr项目,service url
就选择这个https://start.aliyun.com
,spring官网的url
选择jdk的版本,maven类型的项目
选择需要的依赖,选择之后,新生成的项目就会自动加上需要的maven配置,点击next生成一个SpringBoot的项目,不需要自己手工进行配置maven
这个里面没集成Redisson的starter,所以需要手工进行配置,需要注意一下redisson-spring-boot-starter
和SpringBoot
对应的版本关系
pom.xml
文件加上redisson-spring-boot-starter
配置,然后reimport
引入jar
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.15.6</version>
</dependency>
对于Redisson的配置,有多种方式,可以使用json文件配置,也可以使用yaml文件配置,然后再引进来,如下,新建一个redisson.yml
文件,加上单机版的配置
redisson.yml
singleServerConfig:idleConnectionTimeout: 10000connectTimeout: 10000timeout: 3000retryAttempts: 3retryInterval: 1500password: nullsubscriptionsPerConnection: 5clientName: nulladdress: "redis://127.0.0.1:6379"subscriptionConnectionMinimumIdleSize: 1subscriptionConnectionPoolSize: 50connectionMinimumIdleSize: 32connectionPoolSize: 64database: 0dnsMonitoringInterval: 5000
threads: 8
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {}
"transportMode":"NIO"
在application.yml
里引进redisson.yml
spring:redis:redisson:file: classpath:redisson.yml
另外一种方式是可以直接在application.yml
里直接加上配置,这种方式可能对于使用了分布式配置中心管理的项目更加方便一些
spring:redis:redisson:config: |singleServerConfig:idleConnectionTimeout: 10000connectTimeout: 10000timeout: 3000retryAttempts: 3retryInterval: 1500password: nullsubscriptionsPerConnection: 5clientName: nulladdress: "redis://127.0.0.1:6379"subscriptionConnectionMinimumIdleSize: 1subscriptionConnectionPoolSize: 50connectionMinimumIdleSize: 32connectionPoolSize: 64database: 0dnsMonitoringInterval: 5000threads: 0nettyThreads: 0codec: !<org.redisson.codec.JsonJacksonCodec> {}transportMode: "NIO"
在项目中如果想要自己加上配置,创建一个redisson可以先创建一个Config对象,如何进行设置就可以
Config config = new Config();
config.useSingleServer().setAddress("redis://192.168.8.12
8:6379");
config.setCodec(new StringCodec());
return Redisson.create(config);
翻看redisson-spring-boot-starter的源码,也是创建Config,进行设置,这个starter为我们提供了自动配置功能,源码路径:org.redisson.spring.starter.RedissonAutoConfiguration#redisson
public RedissonClient redisson() throws IOException {Config config = null;Method clusterMethod = ReflectionUtils.findMethod(RedisProperties.class, "getCluster");Method timeoutMethod = ReflectionUtils.findMethod(RedisProperties.class, "getTimeout");Object timeoutValue = ReflectionUtils.invokeMethod(timeoutMethod, redisProperties);int timeout;if(null == timeoutValue){timeout = 10000;}else if (!(timeoutValue instanceof Integer)) {Method millisMethod = ReflectionUtils.findMethod(timeoutValue.getClass(), "toMillis");timeout = ((Long) ReflectionUtils.invokeMethod(millisMethod, timeoutValue)).intValue();} else {timeout = (Integer)timeoutValue;}if (redissonProperties.getConfig() != null) {try {config = Config.fromYAML(redissonProperties.getConfig());} catch (IOException e) {try {config = Config.fromJSON(redissonProperties.getConfig());} catch (IOException e1) {throw new IllegalArgumentException("Can't parse config", e1);}}} else if (redissonProperties.getFile() != null) {try {InputStream is = getConfigStream();config = Config.fromYAML(is);} catch (IOException e) {// trying next formattry {InputStream is = getConfigStream();config = Config.fromJSON(is);} catch (IOException e1) {throw new IllegalArgumentException("Can't parse config", e1);}}} else if (redisProperties.getSentinel() != null) {Method nodesMethod = ReflectionUtils.findMethod(Sentinel.class, "getNodes");Object nodesValue = ReflectionUtils.invokeMethod(nodesMethod, redisProperties.getSentinel());String[] nodes;if (nodesValue instanceof String) {nodes = convert(Arrays.asList(((String)nodesValue).split(",")));} else {nodes = convert((List<String>)nodesValue);}config = new Config();config.useSentinelServers().setMasterName(redisProperties.getSentinel().getMaster()).addSentinelAddress(nodes).setDatabase(redisProperties.getDatabase()).setConnectTimeout(timeout).setPassword(redisProperties.getPassword());} else if (clusterMethod != null && ReflectionUtils.invokeMethod(clusterMethod, redisProperties) != null) {Object clusterObject = ReflectionUtils.invokeMethod(clusterMethod, redisProperties);Method nodesMethod = ReflectionUtils.findMethod(clusterObject.getClass(), "getNodes");List<String> nodesObject = (List) ReflectionUtils.invokeMethod(nodesMethod, clusterObject);String[] nodes = convert(nodesObject);config = new Config();config.useClusterServers().addNodeAddress(nodes).setConnectTimeout(timeout).setPassword(redisProperties.getPassword());} else {config = new Config();String prefix = REDIS_PROTOCOL_PREFIX;Method method = ReflectionUtils.findMethod(RedisProperties.class, "isSsl");if (method != null && (Boolean)ReflectionUtils.invokeMethod(method, redisProperties)) {prefix = REDISS_PROTOCOL_PREFIX;}config.useSingleServer().setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort()).setConnectTimeout(timeout).setDatabase(redisProperties.getDatabase()).setPassword(redisProperties.getPassword());}if (redissonAutoConfigurationCustomizers != null) {for (RedissonAutoConfigurationCustomizer customizer : redissonAutoConfigurationCustomizers) {customizer.customize(config);}}return Redisson.create(config);}
在项目中使用的话,一般直接用@Resource
加一个RedissonClient
即可,不需要自己创建了,下面给出使用Redisson API实现的共同关注的人和排名榜的简单例子
package com.example.redission;import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test;
import org.redisson.api.*;
import org.redisson.client.RedisClient;
import org.redisson.client.protocol.ScoredEntry;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.IntStream;@SpringBootTest
class SpringbootRedissionApplicationTests {@Resourceprivate RedissonClient redissonClient;@Testvoid contextLoads() throws ExecutionException, InterruptedException {// 共同关注的人RSet<Object> tom = redissonClient.getSet("tom");tom.addAll(Lists.newArrayList("令狐冲","james","风清扬"));RSet<Object> jack = redissonClient.getSet("jack");jack.addAll(Lists.newArrayList("令狐冲","tim","jack"));System.out.println("共同关注的人:"+tom.readIntersectionAsync("jack").get());// 排名榜RScoredSortedSet<String> school = redissonClient.getScoredSortedSet("school");school.add(60, "tom");school.add(60, "jack");school.add(60, "tim");school.addScore("tom", 20);school.addScore("jack", 10);school.addScore("tim", 30);RFuture<Collection<ScoredEntry<String>>> collectionRFuture = school.entryRangeReversedAsync(0, -1);Iterator<ScoredEntry<String>> iterator = collectionRFuture.get().iterator();System.out.println("成绩从高到低排序");while(iterator.hasNext()) {ScoredEntry<String> next = iterator.next();String value = next.getValue();System.out.println(value);}RFuture<Collection<ScoredEntry<String>>> collectionRFuture1 = school.entryRangeReversedAsync(0, 2);Iterator<ScoredEntry<String>> iterator1 = collectionRFuture1.get().iterator();System.out.println("成绩前三名");while (iterator1.hasNext()) {System.out.println(iterator1.next().getValue());}}}
附录
官网的Readme文档:https://github.com/redisson/redisson/blob/master/redisson-spring-boot-starter/README.md