在 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\"}"