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);
}
}