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