diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java index 0b37e8bab1..1c546386c3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java @@ -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; + @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; } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java index 0e611cba17..bec4af2795 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java @@ -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; + @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 diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SimpleRabbitListenerContainerFactoryConfigurer.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SimpleRabbitListenerContainerFactoryConfigurer.java index 679733b3c2..13980bfbb1 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SimpleRabbitListenerContainerFactoryConfigurer.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/SimpleRabbitListenerContainerFactoryConfigurer.java @@ -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) { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java index aa4e8ba13a..c981b79a17 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java @@ -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 { diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 189afdb0cd..50d5094163 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -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: