Spring AMQP 处理 2 ConnectionFactory

Spring AMQP handling 2 ConnectionFactory

我的应用有 2 个需要连接的兔子实例。

Rabbit1 是我的应用程序的入口点,我的侦听器在这里等待消息

@RabbitListener(queues = "#{myAmqpProperties.getRequest().getQueue()}")

通过常规的Springboot2属性配置

spring:
  rabbitmq:
    host: localhost
    username: myUser
    password: myPass
    port: 5672
    virtual-host: myVhost

这很好用。


现在我需要在另一个 rabbitMQ 实例 Rabbit2 上发送 rabbit 消息。 所以我创建了一个配置 class 构建 rabbitTemplete 及其关联的 connectionFactory。

package com.mycompany.socle.amqp.ocr;

import com.mycompany.doccontrol.messaging.app.AppMessageConverter;
import com.mycompany.socle.amqp.common.service.CpyAmqpRequestWithReplyToProp;
import com.mycompany.socle.amqp.common.service.CpyAmqpServerProperties;
import com.mycompany.socle.common.bean.SslProperties;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.validation.Valid;

@Configuration
@EnableRabbit
public class OcrAmqpConfiguration {


    @Autowired
    private OcrAmqpProperties ocrAmqpProperties;

    /**
     * Template used to send analysis request.
     *
     * @return the template to use
     * @throws Exception if there are issues while initialising the connection factory.
     */
    @Bean
    public RabbitTemplate appRequestTemplate() throws Exception {
        final RabbitTemplate rabbitTemplate = new RabbitTemplate(ocrConnectionFactory());
        rabbitTemplate.setMessageConverter(new AppMessageConverter());
        @Valid final CpyAmqpRequestWithReplyToProp appProperties = ocrAmqpProperties.getApp().getRequest();
        // Settings to send the request
        rabbitTemplate.setExchange(appProperties.getExchange());
        if (appProperties.getRoutingKey() != null) {
            rabbitTemplate.setRoutingKey(appProperties.getRoutingKey());
        }
        return rabbitTemplate;
    }

    /**
     * Define the Connection factory used to contact the broker.
     *
     * @return the connection factory
     * @throws Exception if there are issues while defining the factory context.
     */
    @Bean
    public CachingConnectionFactory ocrConnectionFactory() throws Exception {
        final CachingConnectionFactory result = new CachingConnectionFactory(builConnectionFactory(ocrAmqpProperties.getRabbitmq()).getObject());
        result.afterPropertiesSet();

        return result;
    }


    private static RabbitConnectionFactoryBean builConnectionFactory(MyAmqpServerProperties pAmqpProperties) {
        RabbitConnectionFactoryBean factory = new RabbitConnectionFactoryBean();

        // Generic connection properties
        factory.setHost(pAmqpProperties.getHost());
        factory.setPort(pAmqpProperties.getPort());
        factory.setUsername(pAmqpProperties.getUsername());
        factory.setPassword(pAmqpProperties.getPassword());
        factory.setVirtualHost(pAmqpProperties.getVirtualHost());

        factory.afterPropertiesSet();

        return factory;
    }

}

class MyAmqpServerProperties 只是一个 属性 class 匹配我在 属性 文件中添加的额外 属性 来定义 Rabbit2 信息。

但是没有生成默认的 SpringBoot ConnectionFactory,我的监听器原来监听 Rabbit1,现在也监听 Rabbit2。

我看到 RabbitAutoConfiguration java 文档说:

  • Registers the following beans: * *
  • {@link org.springframework.amqp.rabbit.core.RabbitTemplate RabbitTemplate} if there * is no other bean of the same type in the context.
  • *
  • {@link org.springframework.amqp.rabbit.connection.CachingConnectionFactory * CachingConnectionFactory} instance if there is no other bean of the same type in the * context.

并且在代码中有注解

@ConditionalOnMissingBean(ConnectionFactory.class)

=> 如果我删除 ocrConnectionFactory 方法的 @Bean,它工作正常,但是我需要在 spring 上下文中注册 ocrConnectionFactory 以进行监视 ... 那么有没有一种方法可以在默认生成后注册它,或者其他一些属性来强制默认生成正常生成?

没有。如果您没有,引导将只配置一个。如果配置一个,则必须同时配置两者。