1.消息发送
RedisTemplate支持Pub/Sub功能,调用convertAndSend方法可以发送一条消息:
@Autowired
private RedisTemplate<String, String> redisTemplate;
/**
* redis生产者测试
* @param data
* @return
*/
@GetMapping("/send1")
String send1(String data) {
redisTemplate.convertAndSend("test", data);
return "success";
}
convertAndSend方法用于向channel发送消息。第一个参数是channel的名称,第二个参数的消息的具体内容。redisTemplate将消息序列化成字节后发送到Redis Server。
2.消息订阅和接收
为了订阅频道test的消息,需要实现MessageListener接口的onMessage方法,代码如下:
public class MyRedisChannelListener implements MessageListener {
private Log log= LogFactory.getLog(MyRedisChannelListener.class);
@Override
public void onMessage(Message message, byte[] bytes) {
log.info("============>>>>> onMessage");
byte[] channel=message.getChannel();
byte[] body=message.getBody();
try {
String title=new String(channel,"UTF-8");
String content=new String(body,"UTF-8");
log.info("消息频道名称:"+title);
log.info("消息内容是:"+content);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
Message:
通过调用getBody()方法回去消息的内容,getChannel()返回channel名称,他们返回的格式都是是字节数组,因为我们在发送的时候使用的是StringRedisTemplate,也就是发送的时候消息的编码是StringRedisTemplate定义的序列化策略来转换成字节的,因此我们需要选择正确的序列化策略将字节数组转换为我们需要的对象。
convertAndSend方法:
public void convertAndSend(String channel, Object message) {
Assert.hasText(channel, "a non-empty channel is required");
byte[] rawChannel = this.rawString(channel);
byte[] rawMessage = this.rawValue(message);
this.execute((connection) -> {
connection.publish(rawChannel, rawMessage);
return null;
}, true);
}
private byte[] rawString(String key) {
return this.stringSerializer.serialize(key);
}
private byte[] rawValue(Object value) {
return this.valueSerializer == null && value instanceof byte[] ? (byte[])((byte[])value) : this.valueSerializer.serialize(value);
}
Pattern:订阅模式
配置MessageListener来监听Channel消息。
@Configuration
public class ChannelMessageConfig {
@Bean
MessageListenerAdapter listenerAdapter() {
return new MessageListenerAdapter(new MyRedisChannelListener());
}
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,MessageListenerAdapter listenerAdapter)
{
RedisMessageListenerContainer container=new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter,new PatternTopic("test*"));
return container;
}
}
MessageListenerAdapter 主要用来对消息进行序列化工作,默认采用StringRedisSerializer。
RedisMessageListenerContainer的主要作用是在Redis客户端接收到消息后,通过PatternTopic派发消息到对应的消息监听者,并构造一个线程池任务来调用MessageListener。