首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >spring监听器通过jms配置交换并绑定队列。

spring监听器通过jms配置交换并绑定队列。
EN

Stack Overflow用户
提问于 2021-12-06 23:51:01
回答 2查看 834关注 0票数 0

我有个与spring有关的项目

我在试着和交易所合作。我创建了4个监听器,默认情况下它们都被绑定到名为“jms.durable.queues”的交换中。即使我创建自己的交换并将队列手动绑定在兔子控制台上,spring仍然在创建默认的exchange。

我如何创建自己的队列并绑定到我的交换中,或者禁用spring来创建队列并绑定到默认的exchange‘jms.durable.Quees’?

我的配置类

代码语言:javascript
复制
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);
    }


}

我的听众

代码语言:javascript
复制
    @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){
    }

依赖关系

代码语言:javascript
复制
    implementation 'org.springframework:spring-jms:5.3.13'
    implementation 'com.rabbitmq.jms:rabbitmq-jms:2.3.0'

我看过RMQDestination.class,我能用它来创建两个交换和队列吗?在spring配置上是否有以编程方式管理目的地的spring解析器?

示例为伪代码。

代码语言:javascript
复制
someSpringResolverDestination.setDestination(new RMQDestination());
someSpringResolverDestination.setDestination(new RMQDestination());
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-07 03:49:20

请参阅RabbitMQ JMS:https://github.com/rabbitmq/rabbitmq-jms-client/blob/main/src/main/java/com/rabbitmq/jms/admin/RMQDestination.java中该类的源代码。

由于没有显式地提供交换,所以队列名实际上是绑定到默认交换的。

请参阅更多关于此JMS客户机的文档,以及如何为特定的交换和绑定手动声明目的地:https://www.rabbitmq.com/jms-client.html

更新

请参阅更接近的文档:https://www.rabbitmq.com/jms-client.html#destination-interoperability

代码语言:javascript
复制
@Bean
public Destination jmsDestination() {
    RMQDestination jmsDestination = new RMQDestination();
    jmsDestination.setDestinationName("myQueue");
    jmsDestination.setAmqp(true);
    jmsDestination.setAmqpQueueName("rabbitQueueName");
    return jmsDestination;
}

然后查看@JmsListener JavaDocs:

代码语言:javascript
复制
/**
 * The destination name for this listener, resolved through the container-wide
 * {@link org.springframework.jms.support.destination.DestinationResolver} strategy.
 */
String destination();

JmsDestinationAccessor默认使用DynamicDestinationResolver,这可能不会在这里为我们工作,因为到目前为止,它将对jms.durable.queues交换做任何事情。

因此,需要考虑的另一个解决方案是自定义:

代码语言:javascript
复制
/**
 * 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 "";

因此,您需要为DefaultJmsListenerContainerFactory添加一个bean,并将一个BeanFactoryDestinationResolver注入到它的setDestinationResolver(DestinationResolver)中。然后,在您的RMQDestination方法的destination选项中提供一个@JmsListener bean名称,BeanFactory将为您提供一个具有所需的交换和绑定的适当的RMQDestination

票数 1
EN

Stack Overflow用户

发布于 2021-12-08 02:44:01

只是张贴解决方案(因为@Artem Bilan帮助了我)

我在队列中添加了一个连接侦听器的DestinationResolver(),并开始工作。

代码语言:javascript
复制
@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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70253351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档