在 Spring Data Redis 中,要发布一条消息,可以像其他操作(bLPop, bRPop, bRPopLPush, lIndex,...等)一样,使用低级 RedisConnection 或高级 RedisTemplate 类。这两个类都提供发布方法,该方法接受消息和目标通道作为参数。
注意:RedisConnection 需要原始数据(字节数组),但 RedisTemplate 允许将任意对象作为消息传入。
使用 redis-cli 工具订阅名为 hxstrive 的频道,如下:
D:\server\redis-x64-5.0.14.1> redis-cli 127.0.0.1:6379> subscribe hxstrive Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "hxstrive"
下面将分别介绍使用 RedisConnection 和 RedisTemplate 类实现发布消息。RedisTemplate 类的配置如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
// 设置键序列化方式
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 设置简单类型值的序列化方式
redisTemplate.setValueSerializer(new StringRedisSerializer());
// 设置 hash 类型键的序列化方式
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
// 设置 hash 类型值的序列化方式
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
// 设置默认序列化方式
redisTemplate.setDefaultSerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}下面介绍通过 Redis 连接 RedisConnection 类的 publish() 方法发送消息,方法定义如下:
Long publish(byte[] channel, byte[] message)
其中:
channel 频道名
message 消息内容
示例:使用 RedisConnection 向 hxstrive 频道发送一条字符串消息,代码如下:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Spring Data Redis 使用 RedisConnection 推送消息
* @author hxstrive.com 2022/2/26
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class PushRedisConnection {
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Test
public void contextLoads() {
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
// 频道名称
String channelName = "hxstrive";
// 消息内容
String message = "hello redis!";
// 推送一条消息
connection.publish(channelName.getBytes(), message.getBytes());
return null;
}
});
}
}运行示例,redis-cli 客户端将收到消息,如下:
D:\server\redis-x64-5.0.14.1> redis-cli 127.0.0.1:6379> SUBSCRIBE hxstrive Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "hxstrive" 3) (integer) 1 1) "message" 2) "hxstrive" 3) "hello redis!"
下面通过 RedisTemplate 类的 convertAndSend() 方法发送消息,方法定义如下:
public void convertAndSend(String channel, Object message)
其中:
channel 频道名
message 消息内容
示例:使用 RedisTemplate 向 hxstrive 频道发送一条字符串消息,代码如下:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Spring Data Redis 使用 RedisTemplate 推送消息
* @author hxstrive.com 2022/2/26
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class PushRedisTemplate {
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Test
public void contextLoads() {
// 频道名称
String channelName = "hxstrive";
// 消息内容
String message = "hello redis! RedisTemplate";
// 推送一条消息
redisTemplate.convertAndSend(channelName, message);
}
}运行示例,redis-cli 客户端将收到消息,如下:
D:\server\redis-x64-5.0.14.1> redis-cli 127.0.0.1:6379> SUBSCRIBE hxstrive Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "hxstrive" 3) (integer) 1 1) "message" 2) "hxstrive" 3) "hello redis! RedisTemplate"
不知道读者注意到没有,RedisTemplate 的 convertAndSend() 方法的第二个参数是 Object 类型,因此可以传递任何对象。下面将演示使用 User 对象调用 convertAndSend()。如下:
// 用户实体
public class User {
/** 用户ID */
private int id;
/** 用户名 */
private String name;
//...
}
// 调用 convertAndSend() 方法,推送消息
@Test
public void pushObj() {
// 频道名称
String channelName = "hxstrive";
// 消息内容(一个Java对象)
User message = new User();
message.setId(1000);
message.setName("Tom");
// 推送一条消息
jsonSerialRedisTemplate.convertAndSend(channelName, message);
}运行示例,redis-cli 客户端将收到消息,如下:
D:\server\redis-x64-5.0.14.1> redis-cli
127.0.0.1:6379> SUBSCRIBE hxstrive
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "hxstrive"
3) (integer) 1
1) "message"
2) "hxstrive"
3) "{\"id\":1000,\"name\":\"Tom\"}"