Redis整合springboot笔记

redis整合springboot学习笔记

pom引入依赖

需要同时引入spring-boot-starter-data-redis和commons-pool2这2个依赖;

spring-boot-starter-data-redis是官方封装的redis操作依赖,

commons-pool2是redis需要的连接池,不引入这个会导致启动报错.

xml 复制代码
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.5.0</version>
        </dependency>

配置springboot项目内的application.yml或application.properties

yaml 复制代码
spring:
  redis:
    # ip
    host: localhost
    # 端口6379
    port: 6379
    #密码,没有密码则不配置这一项
    password:
    #指定使用redis 16个库中的哪一个,不配置的话,默认配置为0
    database: 0
    lettuce:
      pool:
        min-idle: 0   #连接池最新空闲时间
        max-wait: -1ms  #最大等待时间
        max-active: 8   #最大活跃时间
        max-idle: 8    #最大空闲时间
      shutdown-timeout: 100ms  #连接池关闭超时时间
    timeout: 1000ms  #redis连接超时时间

使用spring-boot-starter-data-redis内置的StringRedisTemplate

要在需要使用redis的地方注入StringRedisTemplate,如

java 复制代码
@Slf4j
@Component
@Validated
public class RedisTool {
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }
    private ObjectMapper objectMapper;
     @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

}    

判断key是否存在

java 复制代码
 public boolean hasKey(@NotNull String strK) {
        Boolean hasKey = stringRedisTemplate.hasKey(strK);
        if (hasKey != null && hasKey) {
            return true;
        } else {
            log.warn("不存在redis key:{}",strK);
            return false;
        }
    }

删除key

java 复制代码
//删除1个key
public void deleteOneKeyIfExist(@NotNull String key) {
        if (this.hasKey(key)) {
            Boolean delete = stringRedisTemplate.delete(key);
            log.info("删除了key:{},删除结果:{}",key, delete);
        }
    }

//删除多个key
public void deleteBatchKeyIfExist(Set<String> keySet) {
        for (String k : keySet) {
            this.deleteOneKeyIfExist(k);
        }
    }    

添加key

java 复制代码
//添加固定的key
public void setKV(@NotNull String strK, String plainStrV) {
        stringRedisTemplate.opsForValue().set(strK, plainStrV);
    }
//添加带超时时间的key,超时时间到期后key会自动删除
    public void setKVTimeoutSeconds(@NotNull String strK, String plainStrV, long seconds) {
        stringRedisTemplate.opsForValue().set(strK, plainStrV, seconds, TimeUnit.SECONDS);
    }
    
    //序列化后 进行set key
    public boolean setKeyAndObjValue(@NotNull String strK, @NotNull Object objV) {
        try {
            String s = objectMapper.writeValueAsString(objV);
            log.warn("jackson序列化:{}", s);
            this.setKV(strK, s);
            return true;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            log.error("jackson序列化失败", e);
            return false;
        }
    }


    public boolean setKeyAndObjValueByTimeoutSeconds(@NotNull String strK, @NotNull Object objV, long seconds) {
        try {
            String s = objectMapper.writeValueAsString(objV);
            log.warn("jackson序列化:{}", s);
            this.setKVTimeoutSeconds(strK, s, seconds);
            return true;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            log.error("jackson序列化失败", e);
            return false;
        }
    }

查询key

java 复制代码
//获取key的字符串值
public String getPlainStrV(@NotNull String srtKey) {
        if (!this.hasKey(srtKey)) {
            return null;
        }
        return stringRedisTemplate.opsForValue().get(srtKey);
    }

//获取key的对象值
    public <T> T getJavaObjByJsonCache(@NotNull String srtKey, Class<T> valueType) {
        if (!this.hasKey(srtKey)) {
            return null;
        }
        String str = stringRedisTemplate.opsForValue().get(srtKey);
        if (StrUtil.isBlank(str)) {
            return null;
        }
        try {
            log.warn("反序列化json str:{} 为Java obj type:{}", str,valueType);
            return objectMapper.readValue(str, valueType);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("json str 反序列化失败", e);
            return null;
        }
    }

通过redis中的pub/sub实现消息发布和订阅

定义RedisPubSubCfg

java 复制代码
package cn.test.redis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;


@Configuration
public class RedisPubSubCfg {

   private final RedisConnectionFactory redisConnectionFactory;
   @Autowired
   public RedisPubSubCfg(RedisConnectionFactory redisConnectionFactory) {
       this.redisConnectionFactory = redisConnectionFactory;
   }

   /**
    * 将消息监听器绑定到消息容器
    * @return RedisMessageListenerContainer
    */
   @Bean
   public RedisMessageListenerContainer messageListenerContainer(){
       RedisMessageListenerContainer container = new RedisMessageListenerContainer();
       container.setConnectionFactory(redisConnectionFactory);

       //------分开订阅监听,使用自定义的消息监听器SubscribeListener-------
       //按名称匹配
       container.addMessageListener(new CitySub(),new ChannelTopic("cityTopic"));
       //按模式匹配
       container.addMessageListener(new TestSub(),new PatternTopic("/aaa/*"));

       return container;
   }

}

自定义消息监听器

java 复制代码
package cn.test.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;

@Slf4j
public class TestSub implements MessageListener {
  
    @Override
    public void onMessage(Message message, byte[] pattern) {

        String s = new String(pattern);
        log.info("redis  sub pattern: "+s);

        String channelReal = new String(message.getChannel());
        log.info("real sub pattern: "+channelReal);

        String body = new String(message.getBody());
        log.info("TestSub 订阅到的消息: "+body);

    }
}


package cn.test.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;

@Slf4j
public class CitySub implements MessageListener {
  
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String body = new String(message.getBody());

        String channel = new String(message.getChannel());
        System.err.println("Topic 名称: "+channel);
        String patternStr = new String(pattern);
        System.err.println("Topic 模式: "+patternStr);
        log.info("CitySub 订阅到的消息: {}",body);
    }
}
相关推荐
Flynt9 小时前
Redis Cluster主节点挂了,为什么"高可用"还全员掉线?我把三次kill的记录翻出来了
数据库·redis·分布式
by2099910 小时前
学会使用std::string类,并理解其内部是如何管理字符串的详细阐述(上)
c++·笔记·字符串·类和对象·string
笑鸿的学习笔记11 小时前
C++笔记之大块顺序写
java·c++·笔记
写后端的胖头鱼11 小时前
一文详解Cache Aside(旁路缓存模式)
redis·缓存·延迟双删·缓存一致
Web3&Basketball12 小时前
用FastAPI+Redis 复刻常驻Agent
redis·bootstrap·fastapi
code_slave(码畜)12 小时前
微服务架构落地:基础服务 —— 报表服务(中篇:元数据、查询引擎、缓存与权限落地)
spring boot·spring cloud·缓存·微服务·架构
山岚的运维笔记12 小时前
ComfyUI NVIDIA安装教程:官方便携版下载+run_nvidia_gpu.bat启动,8G显存Windows实操
运维·服务器·windows·笔记·prompt·aigc·comfyui
ZealSinger13 小时前
Boot4挂起函数丢traceId怎么修
spring boot·kotlin·协程·可观测性
code_slave(码畜)13 小时前
微服务架构落地:基础服务 —— 报表服务(AI 集成篇:AI 增强报表能力)
人工智能·spring boot·spring cloud·微服务·架构
code_slave(码畜)14 小时前
微服务架构落地:公共中间件层总览——不承载业务,只承载稳定性
spring boot·spring cloud·微服务·中间件·架构