diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/AbstractExchangeParser.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/AbstractExchangeParser.java index 13b82e96..08f409eb 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/AbstractExchangeParser.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/AbstractExchangeParser.java @@ -21,6 +21,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; @@ -42,6 +43,8 @@ public abstract class AbstractExchangeParser extends AbstractSingleBeanDefinitio protected static final String BINDING_QUEUE_ATTR = "queue"; + protected static final String BINDING_EXCHANGE_ATTR = "exchange"; + @Override protected boolean shouldGenerateIdAsFallback() { return true; @@ -87,4 +90,20 @@ public abstract class AbstractExchangeParser extends AbstractSingleBeanDefinitio protected abstract AbstractBeanDefinition parseBinding(String exchangeName, Element binding, ParserContext parserContext); + protected void parseDestination(Element binding, ParserContext parserContext, BeanDefinitionBuilder builder) { + String queueAttribute = binding.getAttribute(BINDING_QUEUE_ATTR); + String exchangeAttribute = binding.getAttribute(BINDING_EXCHANGE_ATTR); + boolean hasQueueAttribute = StringUtils.hasText(queueAttribute); + boolean hasExchangeAttribute = StringUtils.hasText(exchangeAttribute); + if (!(hasQueueAttribute ^ hasExchangeAttribute)) { + parserContext.getReaderContext().error("Binding must have exactly one of 'queue' or 'exchange'", binding); + } + if (hasQueueAttribute) { + builder.addPropertyReference("destinationQueue", queueAttribute); + } + if (hasExchangeAttribute) { + builder.addPropertyReference("destinationExchange", exchangeAttribute); + } + } + } diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/DirectExchangeParser.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/DirectExchangeParser.java index 13743515..a57f9450 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/DirectExchangeParser.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/DirectExchangeParser.java @@ -40,7 +40,7 @@ public class DirectExchangeParser extends AbstractExchangeParser { protected AbstractBeanDefinition parseBinding(String exchangeName, Element binding, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(BindingFactoryBean.class); - builder.addPropertyReference("destinationQueue", binding.getAttribute(BINDING_QUEUE_ATTR)); + parseDestination(binding, parserContext, builder); builder.addPropertyValue("exchange", new TypedStringValue(exchangeName)); String bindingKey = binding.getAttribute(BINDING_KEY_ATTR); if (!StringUtils.hasText(bindingKey)) { diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/FanoutExchangeParser.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/FanoutExchangeParser.java index abbcaedb..99ce8561 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/FanoutExchangeParser.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/FanoutExchangeParser.java @@ -36,7 +36,7 @@ public class FanoutExchangeParser extends AbstractExchangeParser { @Override protected AbstractBeanDefinition parseBinding(String exchangeName, Element binding, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(BindingFactoryBean.class); - builder.addPropertyReference("destinationQueue", binding.getAttribute(BINDING_QUEUE_ATTR)); + parseDestination(binding, parserContext, builder); builder.addPropertyValue("exchange", new TypedStringValue(exchangeName)); builder.addPropertyValue("arguments", Collections.emptyMap()); return builder.getBeanDefinition(); diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/HeadersExchangeParser.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/HeadersExchangeParser.java index d59d3627..6c5f6005 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/HeadersExchangeParser.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/HeadersExchangeParser.java @@ -38,7 +38,7 @@ public class HeadersExchangeParser extends AbstractExchangeParser { @Override protected AbstractBeanDefinition parseBinding(String exchangeName, Element binding, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(BindingFactoryBean.class); - builder.addPropertyReference("destinationQueue", binding.getAttribute(BINDING_QUEUE_ATTR)); + parseDestination(binding, parserContext, builder); builder.addPropertyValue("exchange", new TypedStringValue(exchangeName)); ManagedMap map = new ManagedMap(); String key = binding.getAttribute("key"); diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/TopicExchangeParser.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/TopicExchangeParser.java index 3a5b9eff..6554185e 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/TopicExchangeParser.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/TopicExchangeParser.java @@ -41,7 +41,7 @@ public class TopicExchangeParser extends AbstractExchangeParser { @Override protected AbstractBeanDefinition parseBinding(String exchangeName, Element binding, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(BindingFactoryBean.class); - builder.addPropertyReference("destinationQueue", binding.getAttribute(BINDING_QUEUE_ATTR)); + parseDestination(binding, parserContext, builder); builder.addPropertyValue("exchange", new TypedStringValue(exchangeName)); builder.addPropertyValue("routingKey", new TypedStringValue(binding.getAttribute(BINDING_PATTERN_ATTR))); builder.addPropertyValue("arguments", Collections.emptyMap()); diff --git a/spring-rabbit/src/main/resources/org/springframework/amqp/rabbit/config/spring-rabbit-1.0.xsd b/spring-rabbit/src/main/resources/org/springframework/amqp/rabbit/config/spring-rabbit-1.0.xsd index 7451bc89..46aac742 100644 --- a/spring-rabbit/src/main/resources/org/springframework/amqp/rabbit/config/spring-rabbit-1.0.xsd +++ b/spring-rabbit/src/main/resources/org/springframework/amqp/rabbit/config/spring-rabbit-1.0.xsd @@ -441,7 +441,7 @@ - + + + + + + + + + + + diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/config/RabbitNamespaceHandlerTests.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/config/RabbitNamespaceHandlerTests.java index c9fb96fd..a5d2b0ab 100644 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/config/RabbitNamespaceHandlerTests.java +++ b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/config/RabbitNamespaceHandlerTests.java @@ -80,7 +80,7 @@ public final class RabbitNamespaceHandlerTests { public void testBindings() throws Exception { Map bindings = beanFactory.getBeansOfType(Binding.class); // 4 for each exchange type - assertEquals(16, bindings.size()); + assertEquals(17, bindings.size()); } @Test diff --git a/spring-rabbit/src/test/resources/org/springframework/amqp/rabbit/config/RabbitNamespaceHandlerTests-context.xml b/spring-rabbit/src/test/resources/org/springframework/amqp/rabbit/config/RabbitNamespaceHandlerTests-context.xml index a1ecb1b7..3c0bccf0 100644 --- a/spring-rabbit/src/test/resources/org/springframework/amqp/rabbit/config/RabbitNamespaceHandlerTests-context.xml +++ b/spring-rabbit/src/test/resources/org/springframework/amqp/rabbit/config/RabbitNamespaceHandlerTests-context.xml @@ -22,6 +22,7 @@ +