java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Boot 整合 Redis

Spring Boot 整合 Redis详解从基础操作到实战应用

作者:igxia

文章介绍了SpringBoot整合Redis的必要性、步骤及核心数据类型,涵盖分布式锁、缓存注解等高级功能,并提供最佳实践如键命名规范和内存优化,强调二者结合提升应用性能与可扩展性,感兴趣的朋友跟随小编一起看看吧

在现代应用中,缓存 几乎是性能优化的必备手段。Redis 作为高性能的内存数据库,不仅支持键值对缓存,还支持丰富的数据结构(如 List、Set、Hash、ZSet 等),被广泛用于缓存、分布式锁、消息队列、计数器等场景。

Spring Boot 提供了开箱即用的 Redis 集成支持,开发者可以非常方便地在项目中使用 Redis。

一、为什么选择 Redis?

在现代应用开发中,​​Redis​​ 已成为高性能缓存和分布式数据存储的首选方案。作为内存数据结构存储系统,Redis 提供:

Spring Boot 通过 ​​Spring Data Redis​​ 模块提供了与 Redis 的无缝集成,极大简化了开发流程。

二、Spring Boot 整合 Redis 步骤

1. 添加依赖

在 pom.xml 中添加:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId> <!-- 推荐使用 Jedis 客户端 -->
</dependency>

2. 配置 Redis 连接

在 application.yml 中配置:

spring:
  redis:
    host: localhost
    port: 6379
    password: your-password # 如果有密码
    database: 0 # 默认数据库索引
    jedis:
      pool:
        max-active: 8 # 连接池最大连接数
        max-idle: 8   # 连接池最大空闲连接
        min-idle: 2   # 连接池最小空闲连接

3. 配置 RedisTemplate

创建配置类:

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        // 使用Jackson序列化器
        Jackson2JsonRedisSerializer<Object> serializer = 
            new Jackson2JsonRedisSerializer<>(Object.class);
        // 解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(
            om.getPolymorphicTypeValidator(), 
            ObjectMapper.DefaultTyping.NON_FINAL
        );
        serializer.setObjectMapper(om);
        // 设置序列化
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }
}

三、Redis 五大核心数据类型

1. String(字符串)

​特点​​:最基本的数据类型,最大能存储 512MB

​常用场景​​:

​操作示例​​:

@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 设置值
redisTemplate.opsForValue().set("user:1001:name", "Alice");
// 获取值
String name = (String) redisTemplate.opsForValue().get("user:1001:name");
// 自增计数器
redisTemplate.opsForValue().increment("article:1001:views");
// 设置带过期时间(30分钟)
redisTemplate.opsForValue().set("temp:session", "data", 30, TimeUnit.MINUTES);

2. Hash(哈希)

​特点​​:键值对集合,适合存储对象

​常用场景​​:

​操作示例​​:

// 存储用户对象
Map<String, String> userMap = new HashMap<>();
userMap.put("name", "Bob");
userMap.put("age", "30");
userMap.put("email", "bob@example.com");
redisTemplate.opsForHash().putAll("user:1002", userMap);
// 获取单个字段
String email = (String) redisTemplate.opsForHash().get("user:1002", "email");
// 更新单个字段
redisTemplate.opsForHash().put("user:1002", "age", "31");
// 获取所有字段
Map<Object, Object> userData = redisTemplate.opsForHash().entries("user:1002");

3. List(列表)

​特点​​:有序、可重复的字符串集合

​常用场景​​:

​操作示例​​:

// 从左侧插入
redisTemplate.opsForList().leftPush("news:latest", "Article 1");
redisTemplate.opsForList().leftPush("news:latest", "Article 2");
// 从右侧插入
redisTemplate.opsForList().rightPush("news:latest", "Article 3");
// 获取范围数据(0到10)
List<Object> latestNews = redisTemplate.opsForList().range("news:latest", 0, 10);
// 列表长度
Long size = redisTemplate.opsForList().size("news:latest");
// 模拟队列消费
Object article = redisTemplate.opsForList().rightPop("news:queue", 10, TimeUnit.SECONDS);

4. Set(集合)

​特点​​:无序、不可重复的元素集合

​常用场景​​:

​操作示例​​:

// 添加元素
redisTemplate.opsForSet().add("article:1001:tags", "tech", "java", "spring");
// 获取所有元素
Set<Object> tags = redisTemplate.opsForSet().members("article:1001:tags");
// 检查元素是否存在
boolean containsJava = redisTemplate.opsForSet().isMember("article:1001:tags", "java");
// 集合运算(交集)
Set<Object> commonTags = redisTemplate.opsForSet().intersect(
    "article:1001:tags", 
    "article:1002:tags"
);
// 唯一访客统计
redisTemplate.opsForSet().add("article:1001:visitors", "192.168.1.1");
Long visitors = redisTemplate.opsForSet().size("article:1001:visitors");

5. Sorted Set(有序集合)

​特点​​:带分数排序的Set

​常用场景​​:

​操作示例​​:

// 添加带分数的元素
redisTemplate.opsForZSet().add("leaderboard", "player1", 2500);
redisTemplate.opsForZSet().add("leaderboard", "player2", 1800);
redisTemplate.opsForZSet().add("leaderboard", "player3", 3000);
// 获取前3名玩家
Set<ZSetOperations.TypedTuple<Object>> topPlayers = 
    redisTemplate.opsForZSet().reverseRangeWithScores("leaderboard", 0, 2);
// 更新分数
redisTemplate.opsForZSet().incrementScore("leaderboard", "player1", 100);
// 获取玩家排名(从高到低)
Long rank = redisTemplate.opsForZSet().reverseRank("leaderboard", "player2");
// 获取分数段玩家(2000-3000分)
Set<Object> players = redisTemplate.opsForZSet().rangeByScore("leaderboard", 2000, 3000);

四、高级功能实战

1. 分布式锁实现

public boolean tryLock(String lockKey, String requestId, long expireTime) {
    return Boolean.TRUE.equals(redisTemplate.execute((RedisCallback<Boolean>) connection -> {
        // 使用SET命令的NX(不存在才设置)和PX(毫秒过期)选项
        String result = connection.set(
            lockKey.getBytes(),
            requestId.getBytes(),
            Expiration.milliseconds(expireTime),
            RedisStringCommands.SetOption.SET_IF_ABSENT
        );
        return "OK".equals(result);
    }));
}
public boolean releaseLock(String lockKey, String requestId) {
    String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                   "return redis.call('del', KEYS[1]) " +
                   "else return 0 end";
    return Boolean.TRUE.equals(redisTemplate.execute(
        new DefaultRedisScript<>(script, Long.class),
        Collections.singletonList(lockKey),
        requestId
    ));
}

2. 缓存注解使用

@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
    // 数据库查询逻辑
    return userRepository.findById(id).orElse(null);
}
@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
    // 更新数据库
    return userRepository.save(user);
}
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
    userRepository.deleteById(id);
}

3. 发布/订阅模式

// 配置消息监听容器
@Bean
public RedisMessageListenerContainer container(
        RedisConnectionFactory factory,
        MessageListenerAdapter listenerAdapter) {
    RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    container.setConnectionFactory(factory);
    container.addMessageListener(listenerAdapter, new PatternTopic("news.*"));
    return container;
}
// 消息处理器
@Component
public class RedisMessageListener {
    @Autowired
    private SimpMessagingTemplate messagingTemplate;
    public void handleMessage(String message, String channel) {
        // 处理消息并转发到WebSocket
        messagingTemplate.convertAndSend("/topic/" + channel, message);
    }
}
// 发布消息
public void publish(String channel, String message) {
    redisTemplate.convertAndSend(channel, message);
}

五、最佳实践与注意事项

spring:
  redis:
    jedis:
      pool:
        max-active: 50 # 根据负载调整
        max-wait: 200ms
// 获取Redis指标
@Autowired
private RedisConnectionFactory factory;
public void monitor() {
    RedisConnection connection = factory.getConnection();
    Properties info = connection.info();
    System.out.println("内存使用: " + info.getProperty("used_memory_human"));
    System.out.println("连接数: " + info.getProperty("connected_clients"));
}

六、总结

Spring Boot 与 Redis 的结合为开发者提供了强大的数据缓存和处理能力。通过掌握:

  1. ​五大核心数据类型​​的适用场景和操作方法
  2. ​RedisTemplate​​ 的高级用法
  3. ​分布式锁​​、​​发布订阅​​等高级功能
  4. ​生产环境最佳实践

到此这篇关于Spring Boot 整合 Redis详解从基础操作到实战应用的文章就介绍到这了,更多相关Spring Boot 整合 Redis内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文