1.在SpringBoot中配置消息监听容器RedisMessageListenerContainer
//自定义消息监听器
@Component
public class RedisConsumer implements MessageListener {
@Autowired
private RedisTemplate redisTemplate;
@Override
public void onMessage(Message message, byte[] bytes) {
byte[] magBytes = message.getBody();
Object pack = redisTemplate.getValueSerializer().deserialize(magBytes);
String topic = (String) redisTemplate.getKeySerializer().deserialize(bytes);
System.out.println(topic + pack.toString());
}
}
@Bean
public ThreadPoolTaskScheduler initTaskScheduler () {
if (threadPoolTaskScheduler != null) {
return threadPoolTaskScheduler;
}
threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(20);
return threadPoolTaskScheduler;
}
@Bean
public RedisMessageListenerContainer initRedisContainer(){
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory); //设置连接工厂
redisMessageListenerContainer.setTaskExecutor(threadPoolTaskScheduler); //设置消息监听和处理的连接池
Topic topicWatch = new ChannelTopic("watch"); //监听的channel
redisMessageListenerContainer.addMessageListener(redisConsumer,topicWatch); //设置监听器和监听channel
redisMessageListenerContainer.setErrorHandler((Throwable var) ->{log.error(var.getMessage());});
return redisMessageListenerContainer;
}
2.消息监听容器RedisMessageListenerContainer的初始化及启动
RedisMessageListenerContainer在进入容器之前的两个关键操作:
(1)redisMessageListenerContainer.setTaskExecutor(threadPoolTaskScheduler);设置线程池,主要用来在接收消息以后可以异步解析,快速返回使连接可以继续监听channel;
private Executor taskExecutor;
public void setTaskExecutor(Executor taskExecutor) {
this.taskExecutor = taskExecutor;
}
(2)redisMessageListenerContainer.addMessageListener(redisConsumer,topicWatch);主要用来初始化监听容器内部维持的监听器和channel之间的映射关系:
private final Map<ByteArrayWrapper, Collection<MessageListener>> patternMapping;
private final Map<ByteArrayWrapper, Collection<MessageListener>> channelMapping;
private final Map<MessageListener, Set<Topic>> listenerTopics;
//初始化
this.patternMapping = new ConcurrentHashMap();
this.channelMapping = new ConcurrentHashMap();
this.listenerTopics = new ConcurrentHashMap();
初始化过程如下:
public void addMessageListener(MessageListener listener, Topic topic) {
this.addMessageListener(listener, (Collection)Collections.singleton(topic));
}
public void addMessageListener(MessageListener listener, Collection<? extends Topic> topics) {
this.addListener(listener, topics);
this.lazyListen();
}
private void addListener(MessageListener listener, Collection<? extends Topic> topics) {
Assert.notNull(listener, "a valid listener is required");
Assert.notEmpty(topics, "at least one topic is required");
List<byte[]> channels = new ArrayList(topics.size