# spring-boot-starter-data-redis
本文精选:https://www.yuque.com/mrcode.cn/note-combat/wxot719u4r6iaoxt
spring-boot-starter-data-redis
的使用在 官方文档 - 3.0.6 (opens new window) 中提到,而它依赖的是 spring-data-redis:3.0.6 (opens new window)
# 发布订阅模式使用
需要注意的是:发布订阅模式,需要订阅的客户端在线,才能收到消息,离线期间的消息是收不到的
# 发布消息
package cn.mrcode.handler;
import com.alibaba.fastjson2.JSONObject;
import cn.mrcode.CollectionTaskCreateEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* @author mrcode
* @date 2023/11/15 18:54
*/
@Component
public class CollectionTaskEventHandler {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@EventListener
@Async
public void taskPublish(CollectionTaskCreateEvent event) {
CollectionTaskMsg message = new CollectionTaskMsg();
message.setTime(LocalDateTime.now());
message.setId(event.getId());
// 调用 convertAndSend 发送消息
// 消息内容需要自己转换为 字符串
stringRedisTemplate.convertAndSend(CollectionTaskSubcribe.TOPIC, JSONObject.toJSONString(message));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 订阅消息
订阅消息麻烦一点
# 手动方式
自己获取 connection 然后订阅
stringRedisTemplate.getConnectionFactory()
.getConnection()
.subscribe(listener,"topic 名称".getBytes());
1
2
3
2
3
# spirng 容器方式
暴露 RedisMessageListenerContainer 对象
package cn.mrcode.redis;
import cn.hutool.core.collection.CollectionUtil;
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.RedisMessageListenerContainer;
import java.util.List;
/**
* @author mrcode
* @date 2023/11/15 19:03
*/
@Configuration
public class MyRedisConfig {
@Autowired(required = false)
private List<MyMessageListener> listeners;
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
if (CollectionUtil.isNotEmpty(listeners)) {
for (MyMessageListener listener : listeners) {
container.addMessageListener(listener, new ChannelTopic(listener.getTopicName()));
}
}
return container;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
MyMessageListener 是我们自己定义的一个接口
package cn.mrcode.redis;
import org.springframework.data.redis.connection.MessageListener;
public interface MyMessageListener extends MessageListener {
/**
* 该消息订阅器要监听的 topic
* @return
*/
String getTopicName();
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
然后实现 MyMessageListener 接口
package cn.mrcode.handler;
import cn.mrcode.redis.MyMessageListener;
import org.springframework.data.redis.connection.Message;
import org.springframework.stereotype.Component;
/**
* @author mrcode
* @date 2023/11/15 19:18
*/
@Component
public class CollectionTaskSubcribe implements MyMessageListener {
public static final String TOPIC = "CollectionTask";
@Override
public void onMessage(Message message, byte[] pattern) {
String json = new String(message.getBody());
// 前面发送的时候,转成的是 json 字符串,这里拿到之后,再用 json 工具反序列化为消息对象就行
System.out.println(json);
}
@Override
public String getTopicName() {
return TOPIC;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27