My app has 2 rabbit instances it needs to connect to.
Rabbit1 is an entry point to my app, where my listener waits for message and
@RabbitListener(queues = "#{myAmqpProperties.getRequest().getQueue()}")
it is configured through regular Springboot2 properties
spring:
rabbitmq:
host: localhost
username: myUser
password: myPass
port: 5672
virtual-host: myVhost
This works fine.
Now I need to send rabbit message on another rabbitMQ instance, Rabbit2. So I created a configuration class building the rabbitTemplete and its associated 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;
}
}
The class MyAmqpServerProperties is just a property class matching extra property i added in my property file to define Rabbit2 info.
But then the default SpringBoot ConnectionFactory is NOT generated, and my listener which listened originaly to Rabbit1, now also listen to Rabbit2.
I see RabbitAutoConfiguration java doc says:
- 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.
And in the code there is the annotation
@ConditionalOnMissingBean(ConnectionFactory.class)
=> If I remove the @Bean of the ocrConnectionFactory method, it works fine, however I need to have the ocrConnectionFactory registered in spring context for monitoring ... So is there a way to either register it AFTER the default one has been generated, or some other properties to force the default one to be generated as normal ?