Springboot通过redisTemplate实现发布订阅

本文详细介绍如何在SpringBoot中利用Redis实现发布订阅功能,包括配置Redis连接、消息监听及序列化过程。通过实例演示了如何创建监听器、处理消息,并展示了两种实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Springboot通过redisTemplate实现发布订阅

要点:

RedisMessageListenerContainer Redis订阅发布的监听容器,你的消息发布、订阅配置都必须在这里面实现
* addMessageListener(MessageListenerAdapter,PatternTopic) 新增订阅频道及订阅者,订阅者必须有相关方法处理收到的消息。
* setTopicSerializer(RedisSerializer) 对频道内容进行序列化解析

MessageListenerAdapter 监听适配器

  • MessageListenerAdapter(Object , defaultListenerMethod) 订阅者及其方法

redisTemplate redis模版类

  • convertAndSend(String channel, Object message) 消息发布

第一种:

RedisConfig核心类,实现了Redis连接,订阅以及发布配置

package com.example.demo.config;

import com.example.demo.project.MessageReceive1;
import com.example.demo.project.MessageReceive2;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 使用Jackson2JsonRedisSerialize 替换默认的jdkSerializeable序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        // 设置value的序列化规则和 key的序列化规则
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * redis消息监听器容器
     * 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
     * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
     * @param redisConnectionFactory
     * @param listenerAdapter1
     * @return
     */
    //序列化对象(特别注意:发布的时候需要设置序列化;订阅方也需要设置序列化)
    @Bean
    public RedisMessageListenerContainer container1(RedisConnectionFactory redisConnectionFactory, MessageListenerAdapter listenerAdapter1, MessageListenerAdapter listenerAdapter2) {
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
        redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
        // 订阅多个频道
        redisMessageListenerContainer.addMessageListener(listenerAdapter1, new PatternTopic("test1"));
        redisMessageListenerContainer.addMessageListener(listenerAdapter1, new PatternTopic("test2"));
        //不同的订阅者
        redisMessageListenerContainer.addMessageListener(listenerAdapter2, new PatternTopic("test2"));

        //序列化对象(特别注意:发布的时候需要设置序列化;订阅方也需要设置序列化)
        Jackson2JsonRedisSerializer seria = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        seria.setObjectMapper(objectMapper);
        redisMessageListenerContainer.setTopicSerializer(seria);
        return redisMessageListenerContainer;
    }


    //表示监听一个频道
    @Bean
    public MessageListenerAdapter listenerAdapter1(MessageReceive1 messageReceive1) {
        //这个地方 是给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“MessageReceive1 ”
        return new MessageListenerAdapter(messageReceive1, "getMessage");
    }

    //表示监听一个频道
    @Bean
    public MessageListenerAdapter listenerAdapter2(MessageReceive2 messageReceive2) {
        //这个地方 是给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“MessageReceive2 ”
        return new MessageListenerAdapter(messageReceive2, "getMessage");
    }
}

被消费的对象(即传输的数据)

@Data
public class Person implements Serializable {
    private final long serialVersionUID = 1L;

    private String id;

    private String userName;

    private String memberName;

    private String password;

    private String email;

    private String status;

    private String pwdSalt;

}

客户端:

@Component
public class MessageReceive1 {
    public void getMessage(String object) {
//序列化对象(特别注意:发布的时候需要设置序列化;订阅方也需要设置序列化)
        Jackson2JsonRedisSerializer seria = new Jackson2JsonRedisSerializer(Person.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        seria.setObjectMapper(objectMapper);
        Person user = (Person) seria.deserialize(object.getBytes());
        System.out.println("消息客户端1号:" + user.toString());
    }
}
@Component
public class MessageReceive2 {
    public void getMessage(String object) {
//序列化对象(特别注意:发布的时候需要设置序列化;订阅方也需要设置序列化)
        Jackson2JsonRedisSerializer seria = new Jackson2JsonRedisSerializer(Person.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        seria.setObjectMapper(objectMapper);
        Person user = (Person) seria.deserialize(object.getBytes());
        System.out.println("消息客户端2号:" + user);
    }
}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestPack {
    @Resource
    private RedisTemplate redisTemplate;
    @Test
    public void test() {
        Person person1 = new Person();
        person1.setId("001");
        person1.setUserName("一号");
        Person person2 = new Person();
        person2.setId("002");
        person2.setUserName("二号");
        redisTemplate.convertAndSend("test1", person1);
        redisTemplate.convertAndSend("test2", person2);
    }
}

第二种(简单版):

配置类:

@Configuration
public class MyRedisConf {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 使用Jackson2JsonRedisSerialize 替换默认的jdkSerializeable序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        // 设置value的序列化规则和 key的序列化规则
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                                   MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(listenerAdapter, new PatternTopic("test1"));
        return container;
    }

    /**
     * 绑定消息监听者和接收监听的方法,必须要注入这个监听器,不然会报错
     */
    @Bean
    public MessageListenerAdapter listenerAdapter() {
        return new MessageListenerAdapter(new Receiver(), "receiveMessage");
    }
}

@Slf4j
class Receiver {
    public void receiveMessage(String message) {
        System.out.println(message);
    }
}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestPack {
    @Resource
    private RedisTemplate redisTemplate;
    @Test
    public void test(){
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
            redisTemplate.convertAndSend("test1","这是我发送的第"+i+"个消息");
        }
    }

}
### 回答1: 可以使用 RedisTemplate 实现发布订阅消息,具体实现可以参考以下代码: 1. 配置 RedisTemplate ``` @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } } ``` 2. 发布消息 ``` @Autowired private RedisTemplate<String, Object> redisTemplate; public void publish(String channel, Object message) { redisTemplate.convertAndSend(channel, message); } ``` 3. 订阅消息 ``` @Component public class RedisMessageSubscriber implements MessageListener { @Override public void onMessage(Message message, byte[] bytes) { String channel = new String(message.getChannel()); Object messageBody = redisTemplate.getValueSerializer().deserialize(message.getBody()); // 处理消息 } @Autowired private RedisTemplate<String, Object> redisTemplate; @PostConstruct public void subscribe() { redisTemplate.execute((RedisCallback<Void>) connection -> { connection.subscribe(this::onMessage, "channel1".getBytes()); return null; }); } } ``` 以上代码实现了一个简单的发布订阅消息功能,可以根据实际需求进行修改和扩展。 ### 回答2: Spring Boot是一个基于Java的开源框架,它提供了快速构建应用程序的能力。Redis是一个高性能的键值对存储数据库,可以用于缓存、消息队列等场景。 在Spring Boot中整合Redis实现发布订阅消息可以使用Redisson这个开源框架。下面是一个示例: 首先,在pom.xml文件中添加Redisson的依赖: ```xml <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.15.1</version> </dependency> ``` 然后,在application.properties文件中配置Redis连接信息: ```properties spring.redis.host=localhost spring.redis.port=6379 ``` 接下来,创建一个消息发布者: ```java @Component public class MessagePublisher { @Autowired private RedissonClient redissonClient; public void publishMessage(String channel, String message) { RTopic<String> topic = redissonClient.getTopic(channel); topic.publish(message); } } ``` 再创建一个消息订阅者: ```java @Component public class MessageSubscriber { @PostConstruct public void subscribeMessages() { RPatternTopic<String> topic = redissonClient.getPatternTopic("messages.*"); topic.addListener(new PatternMessageListener<String>() { @Override public void onMessage(CharSequence pattern, CharSequence channel, String message) { // 处理消息 System.out.println("Received message: " + message); } }); } } ``` 最后,在需要发布消息的地方调用发布者的publishMessage方法即可: ```java @Autowired private MessagePublisher messagePublisher; public void sendMessage() { messagePublisher.publishMessage("messages.test", "Hello, Redis!"); } ``` 以上是一个简单的Spring Boot整合Redis实现发布订阅消息的例子。通过配置Redis连接信息和使用Redisson框架,可以方便地实现消息发布和订阅的功能。 ### 回答3: Spring Boot整合Redis实现发布订阅消息的例子非常简单。首先,我们需要在pom.xml文件中添加Redis和Spring Boot依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 接下来,在application.properties文件中配置Redis的连接信息: ``` spring.redis.host=127.0.0.1 spring.redis.port=6379 ``` 然后,我们创建一个消息发布者和一个消息订阅者的类。发布者负责发布消息,订阅者负责接收并处理消息。 发布者的示例代码如下: ``` @Component public class MessagePublisher { @Autowired private RedisTemplate<String, Object> redisTemplate; public void publish(String channel, String message) { redisTemplate.convertAndSend(channel, message); } } ``` 订阅者的示例代码如下: ``` @Component public class MessageSubscriber { @Autowired private RedisTemplate<String, Object> redisTemplate; private CountDownLatch latch; public MessageSubscriber(CountDownLatch latch) { this.latch = latch; } public void receiveMessage(String message) { System.out.println("Received message: " + message); latch.countDown(); } @Bean public MessageListenerAdapter messageListener() { return new MessageListenerAdapter(this); } @Bean public RedisMessageListenerContainer redisContainer(RedisConnectionFactory connectionFactory, MessageListenerAdapter messageListener) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.addMessageListener(messageListener, new PatternTopic("channel")); // 替换为实际的频道名称 return container; } } ``` 最后,我们创建一个包含main方法的启动类,并在该类中注入发布者和订阅者的实例,并进行消息发布和订阅的测试: ``` @SpringBootApplication public class RedisPubSubExampleApplication { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(RedisPubSubExampleApplication.class, args); MessagePublisher publisher = ctx.getBean(MessagePublisher.class); publisher.publish("channel", "This is a test message"); CountDownLatch latch = ctx.getBean(CountDownLatch.class); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 以上就是使用Spring Boot整合Redis实现发布订阅消息的例子。通过简单的配置和几行代码,我们就可以实现消息的发布和订阅功能。需要注意的是,这只是一个简单的示例,实际应用中可能需要更多的配置和处理逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值