Skip to content

spring-jms – listener exchange and bind queue by jms configuration

I have a project with spring-jms

I’m trying work with exchanges. I created 4 listeners and all of them are been bound into exchange named ‘jms.durable.queues’ by default. Even thought I create my own exchanges and binding my queues manually on rabbit console, spring is creating a default exchange.

How could I create my own queues and bind into my exchanges or disable spring to create queues and bind into default exchange ‘jms.durable.queues’?

My configuration class

import javax.jms.ConnectionFactory;

import com.rabbitmq.jms.admin.RMQConnectionFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;

public class ConnectionQueueConfig {

    public ConnectionFactory jmsConnectionRabbitFactory(@Autowired RabbitProperties rabbitProperties) {
        RMQConnectionFactory connectionFactory = new RMQConnectionFactory();
        return connectionFactory;

    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory( @Autowired ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        return factory;

    public JmsTemplate defaultJmsTemplate(@Autowired ConnectionFactory connectionFactory) {
        return new JmsTemplate(connectionFactory);


My listeners

    @JmsListener(destination = "queue-1-from-exchange-A" )
    public void messageConsumer1(@Payload Message message,  @Headers MessageHeaders headers){

    @JmsListener(destination = "queue-2-from-exchange-A" )
    public void messageConsumer2(@Payload Message message,  @Headers MessageHeaders headers){

    @JmsListener(destination = "queue-1-from-exchange-B" )
    public void messageConsumer3(@Payload Message message,  @Headers MessageHeaders headers){

    @JmsListener(destination = "queue-2-from-exchange-B" )
    public void messageConsumer4(@Payload Message message,  @Headers MessageHeaders headers){


    implementation 'org.springframework:spring-jms:5.3.13'
    implementation 'com.rabbitmq.jms:rabbitmq-jms:2.3.0'

I have seen about RMQDestination.class, can I use it to create my two exchange and queues? Is there any spring resolver to manager destination programatically on spring-jms configuration?

example as pseudo-code

someSpringResolverDestination.setDestination(new RMQDestination());
someSpringResolverDestination.setDestination(new RMQDestination());



See source code of this class in RabbitMQ JMS Client:

Since you don’t provide an exchange explicitly that queue name is really bound to that default exchange.

See more docs about this JMS client and how to declare destinations manually for specific exchange and binding :


See that documentation closer:

public Destination jmsDestination() {
    RMQDestination jmsDestination = new RMQDestination();
    return jmsDestination;

Then look into @JmsListener JavaDocs:

 * The destination name for this listener, resolved through the container-wide
 * {@link} strategy.
String destination();

The JmsDestinationAccessor uses a DynamicDestinationResolver by default, which, probably, is not going to work over here for us since it is going to do whatever you have so far with that jms.durable.queues exchange.

So, another option to consider for your solution is the custom:

 * The bean name of the {@link org.springframework.jms.config.JmsListenerContainerFactory}
 * to use to create the message listener container responsible for serving this endpoint.
 * <p>If not specified, the default container factory is used, if any.
String containerFactory() default "";

So, you need to add a bean for the DefaultJmsListenerContainerFactory and inject into its setDestinationResolver(DestinationResolver) a BeanFactoryDestinationResolver. Then you provide a RMQDestination bean name into that destination option of your @JmsListener method and BeanFactory is going to give you a proper RMQDestination with desired exchange and binding.