【Springboot系列】整合redis+jedis(含源码)

这篇具有很好参考价值的文章主要介绍了【Springboot系列】整合redis+jedis(含源码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Spring Boot集成Redis和Jedis客户端使用Redis有以下主要特点:

​ 👉简单易用只需要添加相关依赖和简单配置,就可以直接在Spring Boot应用中使用Jedis客户端操作Redis。这大大简化了使用Redis的难度。

​ 👉自动配置Spring Boot会根据类路径中的Jedis版本自动配置JedisConnectionFactory。我们只需要注入JedisConnectionFactory即可获取Jedis客户端实例。

​ 👉功能丰富通过Jedis或者Lettuce客户端,我们可以使用Redis的全部功能,如字符串、列表、集合、排序集合、哈希等数据结构,以及事务、管道等功能。

​ 👉高扩展性我们可以很容易切换不同的Redis客户端,如Jedis、Lettuce。也可以根据需要自定义RedisTemplate或添加RedisCacheManager等来改变缓存行为。

​ 👉与Spring Cache集成Spring Boot将Redis Cache Manager与Spring Cache深度集成,我们可以直接使用Spring Cache注解来注解方法和类,实现缓存功能,而不用直接依赖Redis API。

​ 👉与Spring Data Redis集成Spring Data Redis在Jedis和Lettuce基础上提供了更高级的抽象,我们可以调用其Repository接口来操作Redis,这提供了类似JPA的编程体验。

​ 👉多种缓存支持Spring Boot默认集成了多种缓存技术,如Redis、Ehcache、Hazelcast等。我们只需要一行配置即可切换缓存技术,不需要更改业务逻辑代码。

​ 👉健康监控Spring Boot Actuator可以监控RedisConnectionFactory中的连接池状态、等待连接的线程数等信息,方便我们监控Redis的运行状况。

下面我们从以下几个步骤来应用Jedis:

🌵依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.6</version>
</parent>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.22</version>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.22</version>
    <optional>true</optional>
</dependency>

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

🌵配置文件:

server:
  port: 8080  # 设置访问端口

spring:
  redis:
    enable: true
    jedis:
      host: localhost
      port: 6379
      password: 123456
      database: 0
      maxIdle: 100
      minIdle: 0
      maxTotal: 100
      maxWaitMillis: 500
      testOnBorrow: false
      testOnReturn: true

🌵RedisTestController

@RestController
@RequestMapping("/redis")
public class RedisTestController {

    @Autowired
    RedisComponent redisComponent;

    @ResponseBody
    @GetMapping("/test")
    public String test(){
        String val = "aa";
        String key = "testRedisKey";
        redisComponent.set(key, val);
        String retVal = redisComponent.get(key);
        return retVal;
    }
}

🌵JedisConfig

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Slf4j
@Configuration
public class JedisConfig {

    @Value("${spring.redis.jedis.host}")
    private String redisHost;

    @Value("${spring.redis.jedis.port}")
    private Integer redisPort;

    @Value("${spring.redis.jedis.password}")
    private String redisPassword;

    @Value("${spring.redis.jedis.database}")
    private Integer database;

    @Value("${spring.redis.jedis.maxIdle}")
    private Integer maxIdle;

    @Value("${spring.redis.jedis.minIdle}")
    private Integer minIde;

    @Value("${spring.redis.jedis.maxTotal}")
    private Integer maxTotal;

    @Value("${spring.redis.jedis.maxWaitMillis}")
    private Long maxWaitMillis;

    @Value("${spring.redis.jedis.testOnBorrow}")
    private Boolean testOnBorrow;

    @Value("${spring.redis.jedis.testOnReturn}")
    private Boolean testOnReturn;


    @Bean
    public JedisPool jedisPool(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMinIdle(minIde);
        jedisPoolConfig.setMaxTotal(maxTotal);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        jedisPoolConfig.setTestOnBorrow(testOnBorrow);
        jedisPoolConfig.setTestOnReturn(testOnReturn);

        log.info("redis properties {}, jedisPoolConfig={}" ,  this.toString(),JSONObject.toJSONString(jedisPoolConfig));
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, redisHost, redisPort,0, redisPassword, database);
        return jedisPool;
    }

    @Override
    public String toString() {
        return "JedisConfig{" +
                "redisHost='" + redisHost + '\'' +
                ", redisPort=" + redisPort +
                ", redisPassword='" + redisPassword + '\'' +
                ", database=" + database +
                '}';
    }
}

🌵RedisComponent (Redis工具类)

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.Tuple;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * Created   on 2019/8/19.
 */

@Slf4j
// 是否开启redis
@ConditionalOnProperty(prefix = "spring", name = "redis.enable", havingValue = "true")
@Component
public class RedisComponent {

    private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";
    private static final Long RELEASE_SUCCESS = 1L;
    private static final Long retryMill = 1000 * 1000 * 1L;

    @Autowired
    private JedisPool jedisPool;

    /**
     * 获取分布式锁
     *
     * @param lockKey
     * @param requestId
     * @param expireTime 毫秒
     */
    public Boolean tryDistributedLock(String lockKey, String requestId, int expireTime) {
        log.info("tryGetDistributedLock-->>lockKey = {}, requestId = {}, expireTime = {}", lockKey, requestId, expireTime);
        String result = this.setNxxxExpx(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
        log.info("tryGetDistributedLock-->>lockKey = {}, requestId = {}, result = {}", lockKey, requestId, result);
        return LOCK_SUCCESS.equals(result);
    }

    /**
     * @param lockKey       上锁的key
     * @param expireTime    锁的超时时间
     * @param retryTimeNano 最多尝试多久 纳秒单位
     * @return
     * @throws InterruptedException
     */
    public String lock(String lockKey, int expireTime, long retryTimeNano) {
        int rt = 0;
        String key = null;
        try {
            while (true) {
                key = String.valueOf(System.nanoTime());
                String result = this.setNxxxExpx(lockKey, key, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
                if (LOCK_SUCCESS.equals(result)) {
                    return key;
                }
                // 获取锁失败

                rt += retryMill;//每隔1 ms执行一次
                if (rt <= retryTimeNano) { // 下次可以执行
                    Thread.sleep(retryMill);
                } else {
                    return  null;
                }
            }
        } catch (InterruptedException e) {
            return null;
        }

    }


    /**
     * 释放分布式锁
     *
     * @param lockKey   锁
     * @param requestId 请求标识
     * @return 是否释放成功
     */
    public boolean releaseDistributedLock(String lockKey, String requestId) {
        log.info("releaseDistributedLock-->>, lockKey = {}, requestId = {}", lockKey, requestId);
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Object result = this.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
        log.info("releaseDistributedLock, lockKey = {}, requestId = {}, result = {}", lockKey, requestId, result);
        if (RELEASE_SUCCESS.equals(result)) {
            log.info("releaselock>>>>>>>>>>>>>>>> lockKey = {}, requestId = {}", lockKey, requestId);
            return true;
        }
        log.info("锁已释放, lockKey = {}, requestId = {}", lockKey, requestId);
        return false;

    }


    public final <OUT> OUT redisExec(Function<Jedis, OUT> function) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return function.apply(jedis);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("redisExec error, errorMsg = {}", e.getMessage());
            throw e;
        } finally {
            Optional.ofNullable(jedis).ifPresent(j -> j.close());
        }
    }


    public String setNxxxExpx(final String key, final String value, final String nxxx, final String expx,
                              final int time) {
        return redisExec(jedis -> jedis.set(key, value, nxxx, expx, time));
    }

    public Object eval(String script, List<String> keys, List<String> args) {
        return redisExec(jedis -> jedis.eval(script, keys, args));
    }

    public String get(String key) {
        return this.redisExec(redis -> redis.get(key));
    }

    public byte[] getBytes(byte[] key) {
        return this.redisExec(redis -> redis.get(key));
    }

    public void set(String key, String val) {
        this.redisExec(redis -> redis.set(key, val));
    }

    public Long incr(String key) {
        return this.redisExec(redis -> redis.incr(key));
    }

    public Long append(String key, String value) {
        return this.redisExec(redis->redis.append(key, value));
    }
    public void set(String key, String val, int expireSecond) {
        this.redisTxExec(tx -> {
            tx.set(key, val);
            tx.expire(key, expireSecond);
        });
    }

    public Long rpush(String key, String val) {
        return this.redisExec(tx-> tx.rpush(key, val));
    }

    public String lpop(String key) {
        return this.redisExec(tx->tx.lpop(key));
    }

    public void setBytes(byte[] key, byte[] val, int expireSecond) {
        this.redisTxExec(tx -> {
            tx.set(key, val);
            tx.expire(key, expireSecond);
        });
    }

    public Long SAdd(String key, final String... field) {
        return this.redisExec((redis -> redis.sadd(key, field)));
    }

    public Long ZAdd(String key, double score, String mem) {
        return this.redisExec((redis -> redis.zadd(key, score, mem)));
    }

    public Long SRem(String key, final String... field) {
        return this.redisExec((redis -> redis.srem(key, field)));
    }


    public Long IncBy(String key, Long val) {
        return this.redisExec((redis -> redis.incrBy(key, val)));
    }

    public Long del(String key) {
        return this.redisExec(redis -> redis.del(key));
    }

    public Long del(byte[] key) {
        return this.redisExec(redis -> redis.del(key));
    }

    public Long delByte(byte[] key) {
        return this.redisExec(redis -> redis.del(key));
    }

    public Long hdel(String key, String fileds) {
        return this.redisExec(redis -> redis.hdel(key, fileds));
    }

    public Boolean exists(String key) {
        return this.redisExec(redis -> redis.exists(key));
    }

    public Long scard(String key) {
        return this.redisExec(redis -> redis.scard(key));
    }

    public String srandmember(String key) {
        return this.redisExec(redis -> redis.srandmember(key));
    }

    public Set<String> smembers(String key) {
        return this.redisExec(redis -> redis.smembers(key));
    }

    public boolean sismember(String key, String value) {
        return this.redisExec(redis -> redis.sismember(key, value));
    }

    public Boolean hexists(String key, String ele) {
        return this.redisExec(redis -> redis.hexists(key, ele));
    }

    public String hget(String key, String filed) {
        return this.redisExec(redis -> redis.hget(key, filed));
    }

    public Map<String, String> hgetall(String key) {
        return redisExec(redis -> redis.hgetAll(key));
    }

    public Set<String> zrange(String key, Long start, Long end) {
        return this.redisExec(redis -> redis.zrange(key, start, end));
    }


    public Long zadd(String key, double score, String member) {
        return this.redisExec(redis->redis.zadd(key, score, member));
    }

    public Long zrem(String key, String... mem) {
        return this.redisExec(r -> r.zrem(key, mem));
    }

    public Set<String> zrevrange(String key, Long start, Long end) {
        return this.redisExec(redis -> redis.zrevrange(key, start, end));
    }

    public Set<Tuple> zrevrangeWithScores(String key, Long start, Long end) {
        return this.redisExec(redis -> redis.zrevrangeWithScores(key, start, end));
    }


    public Set<Tuple> zrangeWithScores(String key, Long start, Long end) {
        return this.redisExec(redis -> redis.zrangeWithScores(key, start, end));
    }

    public Long zrank(String key, String member) {
        return this.redisExec(redis -> redis.zrank(key, member));
    }

    public Set<String> hkeys(String key) {
        return this.redisExec(redis -> redis.hkeys(key));
    }

    public List<String> lrange(String key, Long start, Long end) {
        return this.redisExec(redis -> redis.lrange(key, start, end));
    }

    public Long expire(String key, int expireSecond) {
        return this.redisExec(redis -> redis.expire(key, expireSecond));
    }

    public Long TTL(String key) {
        return this.redisExec(redis -> redis.ttl(key));
    }


    public void redisTxExec(Consumer<Transaction> consumer) {
        List<Object> result = this.redisExec(jedis -> {
            Transaction tx = jedis.multi();
            consumer.accept(tx);
            return tx.exec();
        });
    }

    public void redisWatchTxExec(Consumer<Transaction> consumer, String... args) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.watch(args);
            Transaction tx = jedis.multi();
            consumer.accept(tx);
            List<Object> execResult = tx.exec();
            log.info("jedis tx result = {}", execResult);
            if (CollectionUtils.isEmpty(execResult)) {
               return;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("redisExec error, errorMsg = {}", e.getMessage());
            throw e;
        } finally {
            Optional.ofNullable(jedis).ifPresent(j -> j.close());
        }
    }
}

简而言之,Spring Boot与Redis和Jedis的深度集成,让Redis变得异常易用和高效。凭借Spring Boot的“自动配置、起步依赖、产生型API”等特性,我们可以快速上手Redis,开发基于Redis的应用,从而享受Redis强大的功能。这大大提高了开发效率和项目的重用性。

掌握Spring Boot与Redis的集成技术,对我们成为一名专业的后端开发者来说是非常有必要的。这是一项值得长期研究与实践的技能。文章来源地址https://www.toymoban.com/news/detail-520564.html

🎁如果需要完整源码请关注公众号"架构殿堂" ,回复 "redis+jedis"即可获得

🔔写在最后

如果大家对相关文章感兴趣,可以关注公众号"架构殿堂",会持续更新AIGC,java基础面试题, netty, spring boot,spring cloud等系列文章,一系列干货随时送达!

到了这里,关于【Springboot系列】整合redis+jedis(含源码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【万字长文】SpringBoot整合SpringSecurity+JWT+Redis完整教程(提供Gitee源码)

    前言:最近在学习SpringSecurity的过程中,参考了很多网上的教程,同时也参考了一些目前主流的开源框架,于是结合自己的思路写了一个SpringBoot整合SpringSecurity+JWT+Redis完整的项目,从0到1写完感觉还是收获到不少的,于是我把我完整的笔记写成博客分享给大家,算是比较全的

    2024年02月15日
    浏览(37)
  • springboot+redis+mysql+quartz-通过Java操作jedis使用pipeline获取缓存数据定时更新数据库

    代码讲解:6-点赞功能-定时持久化到数据库-pipeline+lua-优化pipeline_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1yP411C7dr 代码: blogLike_schedule/like06 · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com) https://gitee.com/flowers-bloom-is-the-sea/XinQiUtilsOrDemo/tree/master/blogLike_schedule/like06 数据库表的

    2024年02月16日
    浏览(43)
  • springboot+redis+mysql+quartz-通过Java操作jedis定时使用lua脚本获取缓存数据并更新数据库

    springboot+redis+mysql+quartz-通过Java操作jedis定时使用lua脚本获取缓存数据并更新数据库 代码讲解:7.1点赞功能-定时持久化到数据库-Java整合lua_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1ZX4y1H7JT/ 代码: blogLike_schedule/like07 · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com) https://gitee

    2024年02月13日
    浏览(51)
  • 【SpringBoot整合系列】SpringBoot整合FastDFS(一)

    FastDFS(Fast Distributed File System)是一款开源的分布式文件系统,它提供了高性能、高可靠性、高扩展性和高容错性的分布式文件存储解决方案。 FastDFS采用了类似于Google File System(GFS)的架构,它的设计目标是解决大规模数据存储和高访问速度的问题。 分布式架构: FastDFS采用

    2024年04月27日
    浏览(41)
  • 【Redis】SpringBoot整合Redis

    SpringData是Spring里专门用来操作数据的模块,其中对redis集成的模块 它提供了对不同的redis客户端的整合比如Lettuce和Jedis,提供了RedisTemplate统一的API来操作redis,而且它支持Redis的发布订阅模式、哨兵和Redis集群,以及Lettuce的响应式编程,支持序列化于反序列化,支持Redis的JD

    2023年04月23日
    浏览(43)
  • 【Springboot系列】SpringBoot整合Jpa

    前言: Spring Boot是一种快速开发框架,它简化了Java应用程序的开发过程。而Jpa(Java Persistence API)是Java持久化规范的一种实现,它提供了一种方便的方式来访问和操作数据库。将Spring Boot与Jpa整合可以更加方便地进行数据库操作,提高开发效率。本文将介绍如何使用Spring Bo

    2024年02月05日
    浏览(41)
  • [SpringBoot系列]SpringBoot如何整合SSMP

    SpringBoot之所以好用,就是它能方便快捷的整合其他技术,这里我们先介绍四种技术的整合: 整合JUnit 整合MyBatis 整合MyBatis-Plus 整合Druid ​ SpringBoot技术的定位用于简化开发,再具体点是简化Spring程序的开发。所以在整合任意技术的时候,如果你想直观感触到简化的效果,你必

    2023年04月23日
    浏览(35)
  • SpringBoot 整合 Redis 缓存

    Spring Boot提供了对Spring Cache抽象的支持,可以很容易地与Redis集成。 在pom.xml文件中添加Spring Boot Starter Redis依赖: 在application.properties或application.yml中配置Redis连接信息: 在Spring Boot应用的主类(通常是带有@SpringBootApplication注解的类)上添加@EnableCaching注解,启用缓存支持: 在

    2024年01月16日
    浏览(53)
  • Springboot 整合 Redis配置

    RedisService接口 RedisServiceImpl 实现类 Redis 配置类

    2024年02月10日
    浏览(40)
  • springboot整合redis配置

    2024年02月11日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包