代码编织梦想

目录

一、Lettuce 集成使用

1. 在 pom.xml 配置文件中引入如下依赖

2. 在 application.properties 配置文件中添加如下配置

3. 测试一下

二、Jedis 集成使用

1. 在 pom.xml 配置文件中引入如下依赖

2. 在 application.properties 配置文件中添加如下配置

3. 测试一下

补充

1. 工具类

2. 分布式锁


在 SpringBoot 中整合 Redis 十分简单,目前来看,对 Redis 的整合支持两种使用方式:Lettuce(推荐) 和 Jedis;默认的是 Lettuce,也是推荐的方式

一、Lettuce 集成使用

默认的 Redis 集成就是 Lettuce,所以直接使用即可

1. 在 pom.xml 配置文件中引入如下依赖

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

2. 在 application.properties 配置文件中添加如下配置

# redis 连接地址,默认格式:redis://user:password@example.com:6379
spring.redis.url = redis://localhost:6379
# 连接池最大活动连接数
spring.redis.lettuce.pool.max-active = 10
# 连接池中最小空闲连接数
spring.redis.lettuce.pool.min-idle = 5
# 最大连接等待时间
spring.redis.lettuce.pool.max-wait = 10ms

3. 测试一下

@SpringBootTest(classes = {StudySpringbootApplication.class})
public class StudySpringbootApplicationTest {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private RedisConnectionFactory redisConnectionFactory;

    @Test
    public void testRedis() {
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.setIfPresent("hello", "lettuce");
        String value = operations.get("hello");
        System.out.println(value); // lettuce
        // org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
        System.out.println(redisConnectionFactory.getClass().getName());
    }
}

二、Jedis 集成使用

因为 Redis 默认集成 Lettuce,要切换到 Jedis 的话,需要对 redis starter 进行分析,进入 RedisAutoConfiguration.class 可看到注入了两个 Bean:redisTemplate 和 StringRedisTemplate;而这两个 Bean 的实现是通过注入 redisConnectionFactory 实现的

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	@ConditionalOnMissingBean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		StringRedisTemplate template = new StringRedisTemplate();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}
}

所以进入 JedisConnectionConfiguration.class 可看到其继承了 RedisConnectionConfiguration,要生效的话,需要 GenericObjectPool.class, JedisConnection.class, Jedis.class 这 3 个类;同理可以分析 LettuceConnectionConfiguration.class,实现原理基本一样

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ GenericObjectPool.class, JedisConnection.class, Jedis.class })
class JedisConnectionConfiguration extends RedisConnectionConfiguration {... ...}

所以,要切换到 Jedis 的话,就需要排除掉 Lettuce 的依赖,并引入 Jedis 依赖即可;那么实现步骤如下

1. 在 pom.xml 配置文件中引入如下依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

2. 在 application.properties 配置文件中添加如下配置

# redis 连接地址,默认格式:redis://user:password@example.com:6379
spring.redis.url = redis://localhost:6379
# 连接池最大活动连接数
spring.redis.jedis.pool.max-active = 10
# 连接池中最小空闲连接数
spring.redis.jedis.pool.min-idle = 5
# 最大连接等待时间
spring.redis.jedis.pool.max-wait = 10ms

3. 测试一下

@SpringBootTest(classes = {StudySpringbootApplication.class})
public class StudySpringbootApplicationTest {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private RedisConnectionFactory redisConnectionFactory;

    @Test
    public void testRedis() {
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.setIfPresent("hello", "jedis");
        String value = operations.get("hello");
        System.out.println(value); // jedis
        // org.springframework.data.redis.connection.jedis.JedisConnectionFactory
        System.out.println(redisConnectionFactory.getClass().getName());
    }
}

补充

1. 工具类

在项目开发中,我们经常会使用 Redis 存储登录用户的信息,需要整理一个工具类,代码如下

public class RedisUtil {
    private static RedisTemplate<String, Object> template;

    static {
        // 此处需要指定 bean 的名字获取, 根据 type 获取会报错, 因为有两个 RedisTamplate 类型的 Bean
        template = SpringContext.getBean("redisTemplate", RedisTemplate.class);
    }

    /**
     * 添加值, 过期时间单位为秒
     */
    public static void set(String key, Object val, Long expire) {
        template.opsForValue().set(key, val, Duration.ofSeconds(expire));
    }

    /**
     * 获取值
     */
    public static <T> T get(String key) {
        return (T)template.opsForValue().get(key);
    }

    /**
     * 删除值
     */
    public static Long delete(String ... keys) {
        return template.delete(Arrays.asList(keys));
    }
}

像这个工具类,因为 set() 方法放入的值可以是任意对象,如果我们放入的对象是一个实体类对象,就会报错,所以我们还需要设置 key,value 序列化参数,在项目的配置类中添加如下代码解决

/**
* RedisTemplate 配置
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);
    StringRedisSerializer keySerializer = new StringRedisSerializer();
    template.setKeySerializer(keySerializer);
    template.setHashKeySerializer(keySerializer);
    GenericJackson2JsonRedisSerializer valSerializer = new GenericJackson2JsonRedisSerializer();
    template.setValueSerializer(valSerializer);
    template.afterPropertiesSet();
    return template;
}

2. 分布式锁

可使用 Redis 实现简单的分布式锁(如果是集群优先考虑 zookeeper),如下是一个简单的分布式锁实现方式

1. 在 RedisUtil.class 工具类下添加如下代码

/**
* 获取分布式锁
*/
public static boolean getDistributedLock(String distributedLockKey, Long expire) {
    //系统时间 + 设置的过期时间(注意此处是毫秒)
    Long expireTime = System.currentTimeMillis() + expire;
    if (template.opsForValue().setIfAbsent(distributedLockKey, expireTime)) {
        return true;
    }
    Object currentDistributedLockVal = get(distributedLockKey);
    if (null != currentDistributedLockVal && Long.parseLong(currentDistributedLockVal.toString()) < System.currentTimeMillis()) {
        Object oldDistributedLockVal = template.opsForValue().getAndSet(distributedLockKey, String.valueOf(expireTime));
        if (null != oldDistributedLockVal && oldDistributedLockVal.equals(currentDistributedLockVal)) {
            return true;
        }
    }
    return false;
}

2. 在项目的定时任务中获取分布式锁

@Component
public class ScheduleTask {
    /**
     * 测试定时任务
     */
    @Scheduled(cron = "0/5 * * * * *")
    public void taskDemo() {
        newScheduleTask("TestTask1", "DISTRIBUTED_LOCK", 10000L, 
            (taskName)-> CommonUtil.printInfo("测试定时任务, 过期时间为: " + RedisUtil.get("DISTRIBUTED_LOCK")));
    }

    /**
     * 定义一个新的定时任务, 建议任务执行间隔时间大于过期时间
     */
    private void newScheduleTask(String taskName, String lockKey, Long expire, SystemTask task) {
        try {
            if (RedisUtil.getDistributedLock(lockKey, expire)) {
                task.execute(taskName);
                CommonUtil.printInfo("定时任务<" + taskName + ">执行结束");
            } else {
                CommonUtil.printErr("定时任务<" + taskName + ">未请求到锁, 不执行任务");
            }
        } catch (Exception e) {
            throw new GlobalException("定时任务<" + taskName + ">执行失败", e);
        } finally {
            RedisUtil.delete(lockKey);
        }
    }
}

在 newScheduleTask() 方法中第三个参数 SystemTask 实际上是一个函数接口,代码如下

@FunctionalInterface
public interface SystemTask {
    void execute(String taskName);
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/pengjinlong521/article/details/129669801

springboot集成redis_java_日月的博客-爱代码爱编程_springboot集成redis

今天,日月在这里教大家如何使用springBoot集成redis,说实话比较简单,网上也有大把的教程。先套用一下网上的简介。 定义 REmote DIctionary Server(Redis) 是一个由Salvatore

Springboot 集成Redis-爱代码爱编程

Springboot 集成Redis 添加Redis依赖 <depency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-re

springboot集成Redis-爱代码爱编程

第一步: 添加依赖 <!-- spring data redis 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starte

SpringBoot 集成 Redis的demo-爱代码爱编程

SpringBoot 集成 Redis 示例 1.引入依赖 <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artif

springboot集成redis_憨憨不敢_的博客-爱代码爱编程

SpringBoot集成Redis 一,导入包: <dependencies> <dependency> <groupId>org.spring

5.docker入门到精通—安装redis集群(理论)-爱代码爱编程

**面试题:**1-2 亿条数据需要缓存,请问如何设计这个存储案例: **回答:**单机单台 100%不可能,肯定是分布式存储,用 redis 如何落地?(一般业界有 3种 解决方案) 方案一、哈希取余分区 2亿条记录就是 2 亿个 k,v,我们单机不行必须要分 布式多机,假设有 3 台机器构成一

6.docker入门到精通—配置3主3从redis集群-爱代码爱编程

【前提】:docker安装了redis:6.0.8镜像 3主3从redis 集群配置 关闭防火墙+启动 docker 后台服务 systemctl start docker 新建 6 个 docker 容器 redis 实例 docker run -d --name redis-node-1

redis(七):持久化:aof和rdb-爱代码爱编程

前言 上一篇介绍了 Redis 实现消息队列的三种方式。这节开始介绍 Redis 的持久化问题。 我们都知道 Redis 是基于内存的数据库,而内存又是易失性的,一旦遇到断电或异常重启等问题时,内存中的数据就会丢失。所以