简体   繁体   English

spring-jms - 通过 jms 配置监听器交换和绑定队列

[英]spring-jms - listener exchange and bind queue by jms configuration

I have a project with spring-jms我有一个 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.我创建了 4 个侦听器,默认情况下它们都绑定到名为“jms.durable.queues”的交换中。 Even thought I create my own exchanges and binding my queues manually on rabbit console, spring is creating a default exchange.即使我在兔子控制台上创建自己的交换并手动绑定我的队列,spring 正在创建一个默认交换。

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'?如何创建自己的队列并绑定到我的交换或禁用 spring 以创建队列并绑定到默认交换“jms.durable.queues”?

My configuration class我的配置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?我已经看到了RMQDestination.class ,我可以用它来创建我的两个交换和队列吗? Is there any spring resolver to manager destination programatically on spring-jms configuration?在 spring-jms 配置中是否有任何 spring 解析器以编程方式管理目标?

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 . 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 .请参阅有关此 JMS 客户端以及如何手动声明目标以进行特定交换和绑定的更多文档: https://www.rabbitmq.com/jms-client.html

Just posting the solution ( as @Artem Bilan has helped me )只是发布解决方案(@Artem Bilan 帮助了我)

I added a DestinationResolver() for connnecting listener to my queues, and worked.我添加了一个DestinationResolver()用于将侦听器连接到我的队列,并且工作。


@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;
}


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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