SpringBoot整合Redis(Lettuce客户端)

快来打我* 2022-10-29 13:28 82阅读 0赞

在这里插入图片描述

文章目录

  • 一. 问题背景
  • 二. 版本说明
  • 三. 解决方案
    • 3.1 引入依赖
    • 3.2 配置Redis
    • 3.3 封装关于Redis的操作
      • 3.3.1 定义接口
      • 3.3.2 实现接口
    • 3.4 测试前期准备
      • 3.4.1 创建controller层
      • 3.4.2 创建Service层
    • 3.5 部署Redis
      • 3.5.1 安装Redis
      • 3.5.2 配置redis.conf
      • 3.5.3 创建并启动Redis容器
    • 3.6 测试

一. 问题背景

了解完了关于Redis的架构后,尝试动手写代码,SpringBoot整合Redis。Redis的客户端有Jedis以及Lettuce,SpringBoot2.x版本默认使用Lettuce了,可见Lettuce效果比较好。

参考自:

  • mall整合Redis实现缓存功能
  • SpringBoot整合Lettuce Redis

二. 版本说明


















技术栈 版本
SpringBoot 2.x以上版本
Redis 6.0.10(以Docker方式运行)

三. 解决方案

3.1 引入依赖

  1. <!--redis依赖配置-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-data-redis</artifactId>
  5. </dependency>
  6. <!-- lettuce pool 缓存连接池-->
  7. <dependency>
  8. <groupId>org.apache.commons</groupId>
  9. <artifactId>commons-pool2</artifactId>
  10. <version>2.9.0</version>
  11. </dependency>

3.2 配置Redis

在yml文件中,spring节点下,配置Redis的信息:

  1. redis:
  2. host: xx.xx.xx.xx # Redis服务器地址
  3. database: 0 # Redis数据库索引(默认为0)
  4. port: 6379 # Redis服务器连接端口
  5. password: 'xxx' # Redis服务器连接密码(默认为空)
  6. lettuce:
  7. pool:
  8. max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
  9. max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
  10. max-idle: 8 # 连接池中的最大空闲连接
  11. min-idle: 0 # 连接池中的最小空闲连接
  12. timeout: 3000ms # 连接超时时间(毫秒)
  13. key:
  14. prefix:
  15. authCode: "portal:authCode:"
  16. expire:
  17. authCode: 20 # 验证码超期时间

注:上面代码中的prefix authCode以及expire authCode的值随便填

自定义RedisTemplate,否则中文的value存到redis里面会乱码,获取出来也会乱码:

  1. package com.ganzalang.gmall.redis.config;
  2. import com.fasterxml.jackson.annotation.JsonAutoDetect;
  3. import com.fasterxml.jackson.annotation.PropertyAccessor;
  4. import com.fasterxml.jackson.databind.ObjectMapper;
  5. import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.Configuration;
  9. import org.springframework.data.redis.connection.RedisConnectionFactory;
  10. import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
  11. import org.springframework.data.redis.core.RedisTemplate;
  12. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
  13. import org.springframework.data.redis.serializer.RedisSerializer;
  14. import org.springframework.data.redis.serializer.StringRedisSerializer;
  15. /** * @Author Androidla * @Date 2021/2/14 13:40 * @Description **/
  16. @Configuration
  17. @Slf4j
  18. public class RedisConfig {
  19. @Bean
  20. public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  21. log.info("RedisConnectionFactory class: {}", redisConnectionFactory.getClass());
  22. RedisSerializer<Object> serializer = redisSerializer();
  23. RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
  24. redisTemplate.setConnectionFactory(redisConnectionFactory);
  25. redisTemplate.setKeySerializer(new StringRedisSerializer());
  26. redisTemplate.setValueSerializer(serializer);
  27. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  28. redisTemplate.setHashValueSerializer(serializer);
  29. redisTemplate.afterPropertiesSet();
  30. return redisTemplate;
  31. }
  32. @Bean
  33. public RedisSerializer<Object> redisSerializer() {
  34. // 创建JSON序列化器
  35. Jackson2JsonRedisSerializer<Object> serializer =
  36. new Jackson2JsonRedisSerializer<>(Object.class);
  37. ObjectMapper objectMapper = new ObjectMapper();
  38. objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  39. // 必须设置,否则无法将json转化为对象,会转化为Map类型
  40. objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
  41. ObjectMapper.DefaultTyping.NON_FINAL);
  42. serializer.setObjectMapper(objectMapper);
  43. return serializer;
  44. }
  45. }

3.3 封装关于Redis的操作

3.3.1 定义接口

  1. package com.ganzalang.gmall.service;
  2. /** * redis操作Service, * 对象和数组都以json形式进行存储 */
  3. public interface RedisService {
  4. /** * 存储数据 * @param key * @param value */
  5. void set(String key, String value);
  6. /** * 获取数据 * @param key * @return */
  7. String get(String key);
  8. /** * 设置超时时间 * @param key * @param expire * @return */
  9. boolean expire(String key, long expire);
  10. /** * 删除数据 * @param key */
  11. void remove(String key);
  12. /** * 自增操作 * @param key * @param delta * @return */
  13. Long increment(String key, long delta);
  14. }

3.3.2 实现接口

  1. package com.ganzalang.gmall.service.impl;
  2. import com.ganzalang.gmall.service.RedisService;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.data.redis.core.StringRedisTemplate;
  5. import org.springframework.stereotype.Service;
  6. import java.util.concurrent.TimeUnit;
  7. /** * redis操作Service的实现类 */
  8. @Service
  9. public class RedisServiceImpl implements RedisService {
  10. @Autowired
  11. private StringRedisTemplate stringRedisTemplate;
  12. @Override
  13. public void set(String key, String value) {
  14. stringRedisTemplate.opsForValue().set(key, value);
  15. }
  16. @Override
  17. public String get(String key) {
  18. return stringRedisTemplate.opsForValue().get(key);
  19. }
  20. @Override
  21. public boolean expire(String key, long expire) {
  22. return stringRedisTemplate.expire(key, expire, TimeUnit.SECONDS);
  23. }
  24. @Override
  25. public void remove(String key) {
  26. stringRedisTemplate.delete(key);
  27. }
  28. @Override
  29. public Long increment(String key, long delta) {
  30. return stringRedisTemplate.opsForValue().increment(key, delta);
  31. }
  32. }

3.4 测试前期准备

3.4.1 创建controller层

  1. package com.ganzalang.gmall.controller;
  2. import com.ganzalang.gmall.service.impl.TestServiceImpl;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.GetMapping;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RestController;
  7. /** * 测试redis是否整合成功 */
  8. @RestController
  9. @RequestMapping("/test")
  10. public class TestController {
  11. @Autowired
  12. private TestServiceImpl testService;
  13. @GetMapping("/redis")
  14. public String testRedis() {
  15. testService.testRedis();
  16. return "success";
  17. }
  18. }

3.4.2 创建Service层

  1. package com.ganzalang.gmall.service.impl;
  2. import com.ganzalang.gmall.service.RedisService;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.stereotype.Service;
  7. @Service
  8. @Slf4j
  9. public class TestServiceImpl {
  10. @Autowired
  11. private RedisService redisService;
  12. @Value("${spring.redis.key.prefix.authCode}")
  13. private String REDIS_KEY_PREFIX_AUTH_CODE;
  14. @Value("${spring.redis.key.expire.authCode}")
  15. private Long AUTH_CODE_EXPIRE_SECONDS;
  16. private static String username = "10010";
  17. public void testRedis() {
  18. log.info("testRedis start......");
  19. log.info("REDIS_KEY_PREFIX_AUTH_CODE: {}", REDIS_KEY_PREFIX_AUTH_CODE);
  20. log.info("AUTH_CODE_EXPIRE_SECONDS: {}", AUTH_CODE_EXPIRE_SECONDS);
  21. // 设置缓存
  22. redisService.set(getAuthKey(), "管理员权限");
  23. // 设置过期时间
  24. redisService.expire(getAuthKey(), AUTH_CODE_EXPIRE_SECONDS);
  25. // 获取缓存
  26. String auth = redisService.get(getAuthKey());
  27. log.info("auth: {}", auth);
  28. }
  29. // 构造redis的key
  30. private String getAuthKey() {
  31. String key = REDIS_KEY_PREFIX_AUTH_CODE + username;
  32. return key;
  33. }
  34. }

3.5 部署Redis

3.5.1 安装Redis

用Docker方式部署:

  1. # 下载最新版的redis的docker镜像
  2. docker pull redis
  3. # 创建挂载数据的地方
  4. mkdir /mydata/redis/data

3.5.2 配置redis.conf

必须以指定redis.conf方式启动redis容器,否则后面会有一堆报错

去网上下载redis.conf文件,并放到/mydata/redis/下,并修改redis.conf的某些内容,修改如下:

  1. 1. 注释掉 bind 127.0.0.1
  2. 2. protected-mode yes改为no,否则无法远程登陆redis
  3. 3. daemonize yes 改为no,否则启动redis容器会一直失败
  4. 4. 强烈建议设置redis密码,在requirepass处设置自己的密码

3.5.3 创建并启动Redis容器

  1. docker run -p xxxx:6379 --name redis \
  2. -v /mydata/redis/redis.conf:/etc/redis/redis.conf \
  3. -v /mydata/redis/data:/data \
  4. -d redis redis-server /etc/redis/redis.conf \
  5. --appendonly yes

解释:

  1. -p xxxx:6379:前者是宿主机的端口,后者是容器的端口。强烈建议修改宿主机的端口
  2. --name:对创建出来的容器起别名
  3. -v:挂载容器数据到宿主机,实现宿主机与容器数据互通
  4. -d:后台运行
  5. --appendonly yes:数据持久化

3.6 测试

启动程序,可以看到如下:
在这里插入图片描述
整合成功

发表评论

表情:
评论列表 (有 0 条评论,82人围观)

还没有评论,来说两句吧...

相关阅读