如何使用不同的接收器创建多个频道? Spring Redis pub / sub

时间:2014-10-10 13:10:39

标签: java spring redis publish-subscribe spring-jms

我使用Redis发布订阅Spring数据,但我在添加超过1个频道时遇到问题。

目前我跟随典型示例,其中通过添加与Receiver类关联的MessageListenerAdapter来配置MessageListenerContainer,如下所示:

enter image description here

以前的作品非常完美,我能够推送和接收消息。 然而,我尝试添加第二个侦听器适配器来创建带有不同接收器的"通道,并且我得到NullPointerException。

enter image description here

错误如下。添加新适配器有不同的方法吗?一般来说,我想动态添加频道。

通过在addMessageListener方法中提供PatternTopic列表,可以添加与一个特定接收器关联的多个通道。

感谢您的帮助

enter image description here

2 个答案:

答案 0 :(得分:2)

我相信在添加MessageListenerAdapter时,Spring Redis存在一个重要的错误。

如果 Receiver 类没有从 MessageListener 扩展(以及实现onMessage),MessageListenerAdapter类中的内部方法MethodInvoker()专门询问Receiver是否为MessageListener(参见下面的最后一行图片)。

enter image description here

要解决此问题,只需从 MessageListener 扩展,然后就可以直接添加其他适配器。

令人遗憾的是,spring-data-redis团队没有在其github页面中启用问题来发布此错误。 https://github.com/spring-projects/spring-data-redis

答案 1 :(得分:0)

如果还有人在寻找,请使用Spring Boot 1.5.X的以下配置

多个频道的

RedisConfig课程:

@Configuration
public class RedisConfig {

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            @Qualifier("notificationListenerAdapter") MessageListenerAdapter notificationListenerAdapter,
                                            @Qualifier("countListenerAdapter") MessageListenerAdapter countListenerAdapter) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(notificationListenerAdapter,  new PatternTopic("notification"));
        container.addMessageListener(countListenerAdapter, new PatternTopic("count"));
        return container;
    }

    @Bean("notificationListenerAdapter")
    MessageListenerAdapter notificationListenerAdapter(RedisReceiver redisReceiver) {
        return new MessageListenerAdapter(redisReceiver, "receiveNotificationMessage");
    }

    @Bean("countListenerAdapter")
    MessageListenerAdapter countListenerAdapter(RedisReceiver redisReceiver) {
        return new MessageListenerAdapter(redisReceiver, "receiveCountMessage");
    }

    @Bean
    RedisReceiver receiver() {
        return new RedisReceiver();
    }

    @Bean
    StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
        return new StringRedisTemplate(connectionFactory);
    }

}

RedisReceiver从频道接收消息。

注意:确保方法名称与上面定义的方法名称匹配。

public class RedisReceiver {

    private static final Logger LOGGER = LoggerFactory.getLogger(RedisReceiver.class);


    public void receiveNotificationMessage(String message) {
        LOGGER.info("Message Received from notification channel: <" + message + ">");

    }

    public void receiveCountMessage(String message) {
        LOGGER.info("Message Received from count channel: <" + message + ">");
    }
}

测试流程:

public class TestMessages {

    private static final Logger LOG = LoggerFactory.getLogger(TestMessages.class);

    private final StringRedisTemplate redisTemplate;

    public TestMessages(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void sendNotification(String message) {

        redisTemplate.convertAndSend("notification", message);

    }

    public void sendCount(String message) {

        redisTemplate.convertAndSend("count", message);

    }
}