Spring Boot使用Redis进行消息的发布与订阅多频道处理

Redis 不仅提供一个NoSQL数据库,同时还提供了一套消息系统。
下面我将Spring Boot使用Redis进行消息的发布与订阅具体的流程分享给大家

首先引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-redis</artifactId>
    <version>2.0.4.RELEASE</version>
</dependency>

1.发送消息

@Service
public class SendService {

    private final static Logger logger = LoggerFactory.getLogger(SendService.class);

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public void sendMessage(String message,String message2) {
        try {
            logger.info("接收到消息:{},{}", message,message2);
            stringRedisTemplate.convertAndSend("myChannel", message);
            stringRedisTemplate.convertAndSend("myChannel2", message2);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }
}

发送消息我们使用StringRedisTemplate来发送键和值均为字符串的消息。往myChannel和myChannel2两个主题发送消息

 2.Redis 配置消息通道

创建一个Redis消息配置类
连接工程我们使用Spring Boot默认的RedisConnectionFactory
我们将在listenerAdapter方法中定义的Bean注册为一个消息监听者,它将监听myChannel和myChannel2两个主题的消息。

因为Receiver类是一个POJO,要将它包装在一个消息监听者适配器(实现了MessageListener接口),这样才能被监听者容器RedisMessageListenerContainer的addMessageListener方法添加到连接工厂中。有了这个适配器,当一个消息到达时,就会调用receiveMesage()方法进行响应。

@Configuration
public class RedisChannelConfig {
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            MessageListenerAdapter listenerAdapter,
                                            MessageListenerAdapter messageListenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //订阅主题myChannel和myChannel2
        container.addMessageListener(listenerAdapter, new PatternTopic("myChannel"));
        container.addMessageListener(messageListenerAdapter, new PatternTopic("myChannel2"));
        //这个container 可以添加多个 messageListener
        return container;
    }

    @Bean
    MessageListenerAdapter listenerAdapter(Receiver receiver) {
        //这个地方 是给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“receiveMessage”
        //也有好几个重载方法,这边默认调用处理器的方法 叫handleMessage 可以自己到源码里面看
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    @Bean
    MessageListenerAdapter messageListenerAdapter(Receiver receiver){
        return new MessageListenerAdapter(receiver, "handleMessage");
    }


}

注意:配置多通道 注入同类bean时 通过方法名来区别具体类

3.处理Receiver 消息接收类的receiveMessage()处理业务

@Service
public class Receiver {

    public void receiveMessage(String message) {
        //具体业务处理方法
    }

    public void handleMessage(String message) {
        System.out.println("接收到消息信息"+message);
    }
}

 到这里一个完整的Spring Boot使用Redis进行消息的发布与订阅过程就打通了


*订阅发布对象

 发布对象时 需要配置发布对象序列化 接收时也需要序列化操作

配置类

@Configuration
public class SubscriberConfig {

    /**
     * 注入消息监听适配器
     */
    @Bean
    public MessageListenerAdapter messageListenerAdapter(Receiver receiver){
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    /**
     * 注入消息监听适配器
     */
    @Bean
    public MessageListenerAdapter messageListenerAdapter2(Receiver receiver){
        return new MessageListenerAdapter(receiver, "handleMessage");
    }

    /**
     * 注入消息监听容器
     */
    @Bean
    public RedisMessageListenerContainer getRedisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory, MessageListenerAdapter messageListenerAdapter, MessageListenerAdapter messageListenerAdapter2){
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();

        redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
        redisMessageListenerContainer.addMessageListener(messageListenerAdapter, new PatternTopic("myChannel"));
        redisMessageListenerContainer.addMessageListener(messageListenerAdapter2, new PatternTopic("myChannel2"));

        //序列化对象(特别注意:发布的时候需要设置序列化;订阅方也需要设置序列化)
        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 RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){

        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        //自定义序列化方式
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }

}

 接收类

@Service
public class Receiver {

    public void receiveMessage(String message) {
        System.out.println("topic1接收到消息");
    }

    public void handleMessage(String message) {
        //序列化对象(特别注意:发布的时候需要设置序列化;订阅方也需要设置序列化)
        Jackson2JsonRedisSerializer seria = new Jackson2JsonRedisSerializer(User.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        seria.setObjectMapper(objectMapper);
        User user = (User)seria.deserialize(message.getBytes());
        System.out.println("接收到消息信息"+user.getUserName()+"信息"+user);
    }

}

 发布消息

@Autowired
private RedisTemplate<String,Object> redisTemplate;


User user = new User();
user.setRealName("六三");
user.setPassword("13434324234");
redisTemplate.convertAndSend("myChannel2", user);

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值