首页 > 数据库 >SpringBoot系列之集成Redission入门与实践教程

SpringBoot系列之集成Redission入门与实践教程

时间:2023-11-14 15:03:22浏览次数:47  
标签:教程 redisson SpringBoot Config redisProperties ReflectionUtils Redission null con


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

SpringBoot系列之集成Redission入门与实践教程_后端

选择jdk的版本,maven类型的项目

SpringBoot系列之集成Redission入门与实践教程_spring_02

选择需要的依赖,选择之后,新生成的项目就会自动加上需要的maven配置,点击next生成一个SpringBoot的项目,不需要自己手工进行配置maven

SpringBoot系列之集成Redission入门与实践教程_spring_03

这个里面没集成Redisson的starter,所以需要手工进行配置,需要注意一下redisson-spring-boot-starterSpringBoot对应的版本关系

SpringBoot系列之集成Redission入门与实践教程_redis_04

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: 10000
  connectTimeout: 10000
  timeout: 3000
  retryAttempts: 3
  retryInterval: 1500
  password: null
  subscriptionsPerConnection: 5
  clientName: null
  address: "redis://127.0.0.1:6379"
  subscriptionConnectionMinimumIdleSize: 1
  subscriptionConnectionPoolSize: 50
  connectionMinimumIdleSize: 32
  connectionPoolSize: 64
  database: 0
  dnsMonitoringInterval: 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: 10000
          connectTimeout: 10000
          timeout: 3000
          retryAttempts: 3
          retryInterval: 1500
          password: null
          subscriptionsPerConnection: 5
          clientName: null
          address: "redis://127.0.0.1:6379"
          subscriptionConnectionMinimumIdleSize: 1
          subscriptionConnectionPoolSize: 50
          connectionMinimumIdleSize: 32
          connectionPoolSize: 64
          database: 0
          dnsMonitoringInterval: 5000
        threads: 0
        nettyThreads: 0
        codec: !<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 format
                try {
                    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 {

    @Resource
    private RedissonClient redissonClient;

    @Test
    void 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


标签:教程,redisson,SpringBoot,Config,redisProperties,ReflectionUtils,Redission,null,con
From: https://blog.51cto.com/u_15704340/8369447

相关文章

  • Redission获取Redis时间
    RScriptscript=redissonClient.getScript(StringCodec.INSTANCE);longcurrentTime=script.eval(RScript.Mode.READ_WRITE,"localtime=redis.call('TIME')"+"localmilliseconds=tim......
  • Markdown使用教程
    Markdown1.介绍Markdown是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档。Markdown语言在2004由约翰·格鲁伯(英语:JohnGruber)创建。Markdown编写的文档可以导出HTML、Word、图像、PDF、Epub等多种格式的文档。Markdown编写的文档后缀为.md,.mark......
  • Smallpdf 1.24.2 安装包与无限期试用安装教程
    https://www.52pojie.cn/thread-1093277-1-1.html三、安装包下载:链接:https://pan.baidu.com/s/13_r7x9YjMnAMP4jlmoGvGg提取码:vw4d安装包大小超过100M,不能上传蓝奏云,只能上传百度网盘了,各位请见谅。四、安装教程:1、打开安装包,会自动安装,安装完在左上角关闭软件(不要直接右上角关闭!)2......
  • 无涯教程-Dart - isNegative函数
    如果数字为负数,则此属性返回true。isNegative-语法num.isNegativeisNegative-示例voidmain(){intposNum=10;intnegNum=-10;print(posNum.isNegative);print(negNum.isNegative);}它将产生以下输出-falsetrue参考链接https://www.......
  • SpringBoot定义拦截器+自定义注解+Redis实现接口防刷(限流)
    实现思路在拦截器Interceptor中拦截请求通过地址+请求uri作为调用者访问接口的区分在Redis中进行计数达到限流目的简单实现定义参数访问周期最大访问次数禁用时长#接口防刷配置,时间单位都是秒.如果second秒内访问次数达到times,就禁用lockTime秒access:lim......
  • SpringBoot2和SpringBoot3有什么区别
    SpringBoot2和SpringBoot3有什么区别1.最低环境的区别Java版本:SpringBoot2的最低版本要求为Java8,支持Java9;而SpringBoot3决定使用Java17作为最低版本,并支持Java19。SpringFramework版本:SpringBoot2基于SpringFramework5开发;而SpringBoot3构建基于SpringFramework6之上。......
  • springboot集成nacos
    一、加pom文件<!--Nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><d......
  • 零基础快速上手STM32开发(手把手保姆级教程)
    零基础快速上手STM32开发(手把手保姆级教程)1.前言作为一名嵌入式工程师,STM32是必须要学习的一款单片机,同时这款单片机资料足够多,而且比较简单,非常适合初学者入门。STM32是一款由STMicroelectronics公司开发的32位微控制器,由于其强大的处理能力和广泛的应用领域,如嵌入式系......
  • C语言程序设计教程3
    1强制类型转换当类型不同时可能导致数据丢失所以需要强制类型转换所以需要强制类型转换,()中间放需要转变的类型2关系操作符>,<,=;>=(大于等于);<=(小于等于);!=(相当于数学里面的“不等于”用于测试不相等);==(用于测试相等),一个=叫做赋值操作符3逻辑操作符&&(逻辑与,”并且“,全真则真,有一......
  • SpringBoot3
    1>实例Demo1正文idea创建空项目springboot3.1File>>New >>Project...>>EmptyProject2项目springboot3,右键新建Model,boot3-01-demo<!--所有的springboot项目都必须集成spring-boot-starter-parent--><parent><groupId>org.springframework......