Auto-configure Rabbit MessageConverter
If a `MessageConverter` bean is available, we now associate it to the created `RabbitTemplate` and `RabbitListenerContainerFactory`. That way, registering a custom `MessageConverter` is all that's needed. The Rabbit auto-configuration is now using the new `ObjectProvider` that offers a nicer API to detect if a primary candidate is available for optional collaborators. Closes gh-5088
This commit is contained in:
parent
360caf3d97
commit
813d86e5e0
|
|
@ -20,6 +20,8 @@ import org.springframework.amqp.rabbit.annotation.EnableRabbit;
|
|||
import org.springframework.amqp.rabbit.config.RabbitListenerConfigUtils;
|
||||
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
|
|
@ -37,6 +39,9 @@ import org.springframework.context.annotation.Configuration;
|
|||
@ConditionalOnClass(EnableRabbit.class)
|
||||
class RabbitAnnotationDrivenConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ObjectProvider<MessageConverter> messageConverter;
|
||||
|
||||
@Autowired
|
||||
private RabbitProperties properties;
|
||||
|
||||
|
|
@ -44,6 +49,7 @@ class RabbitAnnotationDrivenConfiguration {
|
|||
@ConditionalOnMissingBean
|
||||
public SimpleRabbitListenerContainerFactoryConfigurer rabbitListenerContainerFactoryConfigurer() {
|
||||
SimpleRabbitListenerContainerFactoryConfigurer configurer = new SimpleRabbitListenerContainerFactoryConfigurer();
|
||||
configurer.setMessageConverter(this.messageConverter.getIfUnique());
|
||||
configurer.setRabbitProperties(this.properties);
|
||||
return configurer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -25,6 +25,8 @@ import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean;
|
|||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
|
|
@ -86,10 +88,18 @@ public class RabbitAutoConfiguration {
|
|||
@Autowired
|
||||
private ConnectionFactory connectionFactory;
|
||||
|
||||
@Autowired
|
||||
private ObjectProvider<MessageConverter> messageConverter;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(RabbitTemplate.class)
|
||||
public RabbitTemplate rabbitTemplate() {
|
||||
return new RabbitTemplate(this.connectionFactory);
|
||||
RabbitTemplate rabbitTemplate = new RabbitTemplate(this.connectionFactory);
|
||||
MessageConverter messageConverter = this.messageConverter.getIfUnique();
|
||||
if (messageConverter != null) {
|
||||
rabbitTemplate.setMessageConverter(messageConverter);
|
||||
}
|
||||
return rabbitTemplate;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.amqp;
|
|||
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
|
@ -29,8 +30,19 @@ import org.springframework.util.Assert;
|
|||
*/
|
||||
public final class SimpleRabbitListenerContainerFactoryConfigurer {
|
||||
|
||||
private MessageConverter messageConverter;
|
||||
|
||||
private RabbitProperties rabbitProperties;
|
||||
|
||||
/**
|
||||
* Set the {@link MessageConverter} to use or {@code null} if the out-of-the-box
|
||||
* converter should be used.
|
||||
* @param messageConverter the {@link MessageConverter}
|
||||
*/
|
||||
void setMessageConverter(MessageConverter messageConverter) {
|
||||
this.messageConverter = messageConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link RabbitProperties} to use.
|
||||
* @param rabbitProperties the {@link RabbitProperties}
|
||||
|
|
@ -51,6 +63,9 @@ public final class SimpleRabbitListenerContainerFactoryConfigurer {
|
|||
Assert.notNull(factory, "Factory must not be null");
|
||||
Assert.notNull(connectionFactory, "ConnectionFactory must not be null");
|
||||
factory.setConnectionFactory(connectionFactory);
|
||||
if (this.messageConverter != null) {
|
||||
factory.setMessageConverter(this.messageConverter);
|
||||
}
|
||||
RabbitProperties.Listener listenerConfig = this.rabbitProperties.getListener();
|
||||
factory.setAutoStartup(listenerConfig.isAutoStartup());
|
||||
if (listenerConfig.getAcknowledgeMode() != null) {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import org.springframework.boot.test.EnvironmentTestUtils;
|
|||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
|
@ -128,6 +129,15 @@ public class RabbitAutoConfigurationTests {
|
|||
assertThat(connectionFactory.getVirtualHost()).isEqualTo("/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRabbitTemplateMessageConverters() {
|
||||
load(MessageConvertersConfiguration.class);
|
||||
RabbitTemplate rabbitTemplate = this.context
|
||||
.getBean(RabbitTemplate.class);
|
||||
assertThat(rabbitTemplate.getMessageConverter()).isSameAs(
|
||||
this.context.getBean("myMessageConverter"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionFactoryBackOff() {
|
||||
load(TestConfiguration2.class);
|
||||
|
|
@ -187,7 +197,8 @@ public class RabbitAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
public void testRabbitListenerContainerFactoryWithCustomSettings() {
|
||||
load(TestConfiguration.class, "spring.rabbitmq.listener.autoStartup:false",
|
||||
load(MessageConvertersConfiguration.class,
|
||||
"spring.rabbitmq.listener.autoStartup:false",
|
||||
"spring.rabbitmq.listener.acknowledgeMode:manual",
|
||||
"spring.rabbitmq.listener.concurrency:5",
|
||||
"spring.rabbitmq.listener.maxConcurrency:10",
|
||||
|
|
@ -204,6 +215,8 @@ public class RabbitAutoConfigurationTests {
|
|||
assertThat(dfa.getPropertyValue("maxConcurrentConsumers")).isEqualTo(10);
|
||||
assertThat(dfa.getPropertyValue("prefetchCount")).isEqualTo(40);
|
||||
assertThat(dfa.getPropertyValue("txSize")).isEqualTo(20);
|
||||
assertThat(dfa.getPropertyValue("messageConverter")).isSameAs(
|
||||
this.context.getBean("myMessageConverter"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -325,6 +338,22 @@ public class RabbitAutoConfigurationTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class MessageConvertersConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public MessageConverter myMessageConverter() {
|
||||
return mock(MessageConverter.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageConverter anotherMessageConverter() {
|
||||
return mock(MessageConverter.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRabbit
|
||||
protected static class EnableRabbitConfiguration {
|
||||
|
|
|
|||
|
|
@ -3734,7 +3734,8 @@ directly into your own beans:
|
|||
----
|
||||
|
||||
NOTE: {spring-amqp-javadoc}/rabbit/core/RabbitMessagingTemplate.{dc-ext}[`RabbitMessagingTemplate`]
|
||||
can be injected in a similar manner.
|
||||
can be injected in a similar manner. If a `MessageConverter` bean is defined, it is associated
|
||||
automatically to the auto-configured `AmqpTemplate`.
|
||||
|
||||
Any `org.springframework.amqp.core.Queue` that is defined as a bean will be automatically
|
||||
used to declare a corresponding queue on the RabbitMQ instance if necessary.
|
||||
|
|
@ -3745,7 +3746,8 @@ used to declare a corresponding queue on the RabbitMQ instance if necessary.
|
|||
==== Receiving a message
|
||||
When the Rabbit infrastructure is present, any bean can be annotated with
|
||||
`@RabbitListener` to create a listener endpoint. If no `RabbitListenerContainerFactory`
|
||||
has been defined, a default one is configured automatically.
|
||||
has been defined, a default one is configured automatically. If a `MessageConverter`
|
||||
beans is defined, is is associated automatically to the default factory.
|
||||
|
||||
The following component creates a listener endpoint on the `someQueue` queue:
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue