3

I'm prototyping an application to test spring messaging features for a future application.

One thing I know we will need is to handle topics and queues from activemq in the same application. So, in the same bean I should have a method annotated by @JmsListener that will hear a queue and another that will hear a topic. Is that possible?

What is the simpler way to do that? I saw some answers to use topics with spring-jms like this one but in that case I imagine I will need to create two DefaultMessageListenerContainer, one for a topic and another for a queue. This is the best solution?

Is there any annotation approach for this issue?

Community
  • 1
  • 1
Raphael do Vale
  • 931
  • 2
  • 11
  • 28

2 Answers2

8

Here is a full example of how to set up a second container factory for topics with spring boot:

JmsDemoApplication.java:

package net.lenthe;

import javax.jms.ConnectionFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;

@SpringBootApplication
public class JmsDemoApplication {

    @Autowired
    private ConnectionFactory connectionFactory;

    @Bean(name = "topicJmsListenerContainerFactory")
    public DefaultJmsListenerContainerFactory getTopicFactory() {
        DefaultJmsListenerContainerFactory f = new  DefaultJmsListenerContainerFactory();
        f.setConnectionFactory(connectionFactory);
        f.setSessionTransacted(true);
        f.setPubSubDomain(true);
        return f;
    }

    public static void main(String[] args) {
        SpringApplication.run(JmsDemoApplication.class, args);
    }
}

MessageListenerBean.java:

package net.lenthe;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class MessageListenerBean {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @JmsListener(destination = "myMessageTopic", containerFactory = "topicJmsListenerContainerFactory") 
    public void processTopicMessage(String content) {
        logger.info("Received topic message.  Content is " + content);
    }

    @JmsListener(destination = "myMessageQueue") 
    public void processQueueMessage(String content) {
        logger.info("Received queue message.  Content is " + content);
    }
}
J. Lenthe
  • 1,330
  • 10
  • 10
1

The framework will take care of creating a container for each @JmsListener; you just need to tell it which container factory to use via the containerFactory property.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179