简体   繁体   中英

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;

@EnableJms
@Configuration
public class ConnectionQueueConfig {

    @Bean
    public ConnectionFactory jmsConnectionRabbitFactory(@Autowired RabbitProperties rabbitProperties) {
        RMQConnectionFactory connectionFactory = new RMQConnectionFactory();
        connectionFactory.setUsername(rabbitProperties.getUser());
        connectionFactory.setPassword(rabbitProperties.getPass());
        connectionFactory.setVirtualHost(rabbitProperties.getVirtualhost());
        connectionFactory.setHost(rabbitProperties.getHost());
        connectionFactory.setPort(rabbitProperties.getPort());
        return connectionFactory;
    }

    @Bean
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory( @Autowired ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setAutoStartup(true);
        return factory;
    }

    @Bean
    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){
    }

dependencies

    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: https://github.com/rabbitmq/rabbitmq-jms-client/blob/main/src/main/java/com/rabbitmq/jms/admin/RMQDestination.java .

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: https://www.rabbitmq.com/jms-client.html .

Just posting the solution ( as @Artem Bilan has helped me )

I added a DestinationResolver() for connnecting listener to my queues, and worked.


@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory( @Autowired ConnectionFactory connectionFactory) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);

    factory.setDestinationResolver(new DestinationResolver() {
        @Override
        public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain)  throws JMSException {
            RMQDestination jmsDestination = new RMQDestination();
            jmsDestination.setDestinationName(destinationName);
            jmsDestination.setAmqpQueueName(destinationName);
            jmsDestination.setAmqp(true);
            return jmsDestination;
        }
    });
    
    factory.setAutoStartup(true);
    return factory;
}


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM