You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2021/01/12 09:14:49 UTC

[camel] branch rabbitmq updated (5e2562e -> b90c9b3)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a change to branch rabbitmq
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from 5e2562e  CAMEL-16003: camel-spring-rabbitmq - New component using spring client
     new d843565  CAMEL-16003: camel-spring-rabbitmq - New component using spring client
     new b90c9b3  CAMEL-16003: camel-spring-rabbitmq - New component using spring client

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../catalog/docs/spring-rabbitmq-component.adoc    | 120 +++++-
 .../springrabbit/RabbitMQComponentConfigurer.java  |   6 +
 .../springrabbit/RabbitMQEndpointConfigurer.java   |  18 +-
 .../springrabbit/RabbitMQEndpointUriFactory.java   |  20 +-
 .../component/springrabbit/spring-rabbitmq.json    |   9 +-
 .../src/main/docs/spring-rabbitmq-component.adoc   | 120 +++++-
 .../DefaultListenerContainerFactory.java           |   8 +
 .../springrabbit/EndpointMessageListener.java      |   2 +-
 .../component/springrabbit/RabbitMQComponent.java  |  12 +
 .../component/springrabbit/RabbitMQConstants.java  |  46 +--
 .../component/springrabbit/RabbitMQEndpoint.java   | 114 ++++--
 .../springrabbit/RabbitMQMessageConverter.java     | 410 ---------------------
 .../src/test/resources/log4j2.properties           |   6 +-
 .../dsl/SpringRabbitmqComponentBuilderFactory.java |  17 +
 .../dsl/RabbitMQEndpointBuilderFactory.java        | 243 +++++++-----
 .../ROOT/pages/spring-rabbitmq-component.adoc      | 120 +++++-
 16 files changed, 632 insertions(+), 639 deletions(-)
 delete mode 100644 components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQMessageConverter.java


[camel] 01/02: CAMEL-16003: camel-spring-rabbitmq - New component using spring client

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch rabbitmq
in repository https://gitbox.apache.org/repos/asf/camel.git

commit d8435655a8be1a3cc02eeabb429ef7c32e0751d9
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jan 12 09:28:37 2021 +0100

    CAMEL-16003: camel-spring-rabbitmq - New component using spring client
---
 .../catalog/docs/spring-rabbitmq-component.adoc    |   6 +-
 .../springrabbit/RabbitMQEndpointConfigurer.java   |  18 +-
 .../springrabbit/RabbitMQEndpointUriFactory.java   |  20 ++-
 .../component/springrabbit/spring-rabbitmq.json    |   6 +-
 .../src/main/docs/spring-rabbitmq-component.adoc   |   6 +-
 .../DefaultListenerContainerFactory.java           |   7 +
 .../springrabbit/EndpointMessageListener.java      |   2 +-
 .../component/springrabbit/RabbitMQEndpoint.java   |  49 ++++--
 .../dsl/RabbitMQEndpointBuilderFactory.java        | 195 ++++++++++++---------
 .../ROOT/pages/spring-rabbitmq-component.adoc      |   6 +-
 10 files changed, 204 insertions(+), 111 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-rabbitmq-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-rabbitmq-component.adoc
index 04b35cf..16fa6d5 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-rabbitmq-component.adoc
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-rabbitmq-component.adoc
@@ -91,7 +91,7 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (23 parameters):
+=== Query Parameters (25 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -101,6 +101,7 @@ with the following path and query parameters:
 | *disableReplyTo* (common) | Specifies whether Camel ignores the ReplyTo header in messages. If true, Camel does not send a reply back to the destination specified in the ReplyTo header. You can use this option if you want Camel to consume from a route and you do not want Camel to automatically send back a reply message because another component in your code handles the reply message. You can also use this option if you want to use Camel as a proxy between different message brokers and  [...]
 | *routingKey* (common) | Routing key. |  | String
 | *testConnectionOnStartup* (common) | Specifies whether to test the connection on startup. This ensures that when Camel starts that all the JMS consumers have a valid connection to the JMS broker. If a connection cannot be granted then Camel throws an exception on startup. This ensures that Camel is not started with failed connections. The JMS producers is tested as well. | false | boolean
+| *acknowledgeMode* (consumer) | Flag controlling the behaviour of the container with respect to message acknowledgement. The most common usage is to let the container handle the acknowledgements (so the listener doesn't need to know about the channel or the message). Set to AcknowledgeMode.MANUAL if the listener will send the acknowledgements itself using Channel.basicAck(long, boolean). Manual acks are consistent with either a transactional or non-transactional channel, but if you are  [...]
 | *asyncConsumer* (consumer) | Whether the consumer processes the Exchange asynchronously. If enabled then the consumer may pickup the next message from the queue, while the previous message is being processed asynchronously (by the Asynchronous Routing Engine). This means that messages may be processed not 100% strictly in order. If disabled (as default) then the Exchange is fully processed before the consumer will pickup the next message from the queue. | false | boolean
 | *autoDeclare* (consumer) | Specifies whether the consumer should auto declare binding between exchange, queue and routing key when starting. | true | boolean
 | *autoStartup* (consumer) | Specifies whether the consumer container should auto-startup. | true | boolean
@@ -110,6 +111,8 @@ with the following path and query parameters:
 | *deadLetterQueue* (consumer) | The name of the dead letter queue |  | String
 | *deadLetterRoutingKey* (consumer) | The routing key for the dead letter exchange |  | String
 | *exchangeType* (consumer) | The type of the exchange. There are 4 enums and the value can be one of: direct, fanout, headers, topic | direct | String
+| *exclusive* (consumer) | Set to true for an exclusive consumer | false | boolean
+| *noLocal* (consumer) | Set to true for an no-local consumer | false | boolean
 | *queues* (consumer) | The queue(s) to use for consuming messages. Multiple queue names can be separated by comma. |  | String
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
@@ -119,7 +122,6 @@ with the following path and query parameters:
 | *messageConverter* (advanced) | To use a custom MessageConverter so you can be in control how to map to/from a org.springframework.amqp.core.Message. |  | MessageConverter
 | *messagePropertiesConverter* (advanced) | To use a custom MessagePropertiesConverter so you can be in control how to map to/from a org.springframework.amqp.core.MessageProperties. |  | MessagePropertiesConverter
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
-| *transacted* (transaction) | Specifies whether to use transacted mode | false | boolean
 |===
 // endpoint options: END
 
diff --git a/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQEndpointConfigurer.java b/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQEndpointConfigurer.java
index 50377af..c44046b 100644
--- a/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQEndpointConfigurer.java
+++ b/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQEndpointConfigurer.java
@@ -21,6 +21,8 @@ public class RabbitMQEndpointConfigurer extends PropertyConfigurerSupport implem
     public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
         RabbitMQEndpoint target = (RabbitMQEndpoint) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "acknowledgemode":
+        case "acknowledgeMode": target.setAcknowledgeMode(property(camelContext, org.springframework.amqp.core.AcknowledgeMode.class, value)); return true;
         case "args": target.setArgs(property(camelContext, java.util.Map.class, value)); return true;
         case "asyncconsumer":
         case "asyncConsumer": target.setAsyncConsumer(property(camelContext, boolean.class, value)); return true;
@@ -48,12 +50,15 @@ public class RabbitMQEndpointConfigurer extends PropertyConfigurerSupport implem
         case "exchangePattern": target.setExchangePattern(property(camelContext, org.apache.camel.ExchangePattern.class, value)); return true;
         case "exchangetype":
         case "exchangeType": target.setExchangeType(property(camelContext, java.lang.String.class, value)); return true;
+        case "exclusive": target.setExclusive(property(camelContext, boolean.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
         case "messageconverter":
         case "messageConverter": target.setMessageConverter(property(camelContext, org.springframework.amqp.support.converter.MessageConverter.class, value)); return true;
         case "messagepropertiesconverter":
         case "messagePropertiesConverter": target.setMessagePropertiesConverter(property(camelContext, org.apache.camel.component.springrabbit.MessagePropertiesConverter.class, value)); return true;
+        case "nolocal":
+        case "noLocal": target.setNoLocal(property(camelContext, boolean.class, value)); return true;
         case "queues": target.setQueues(property(camelContext, java.lang.String.class, value)); return true;
         case "replytimeout":
         case "replyTimeout": target.setReplyTimeout(property(camelContext, java.time.Duration.class, value).toMillis()); return true;
@@ -62,7 +67,6 @@ public class RabbitMQEndpointConfigurer extends PropertyConfigurerSupport implem
         case "synchronous": target.setSynchronous(property(camelContext, boolean.class, value)); return true;
         case "testconnectiononstartup":
         case "testConnectionOnStartup": target.setTestConnectionOnStartup(property(camelContext, boolean.class, value)); return true;
-        case "transacted": target.setTransacted(property(camelContext, boolean.class, value)); return true;
         default: return false;
         }
     }
@@ -70,6 +74,8 @@ public class RabbitMQEndpointConfigurer extends PropertyConfigurerSupport implem
     @Override
     public Class<?> getOptionType(String name, boolean ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "acknowledgemode":
+        case "acknowledgeMode": return org.springframework.amqp.core.AcknowledgeMode.class;
         case "args": return java.util.Map.class;
         case "asyncconsumer":
         case "asyncConsumer": return boolean.class;
@@ -97,12 +103,15 @@ public class RabbitMQEndpointConfigurer extends PropertyConfigurerSupport implem
         case "exchangePattern": return org.apache.camel.ExchangePattern.class;
         case "exchangetype":
         case "exchangeType": return java.lang.String.class;
+        case "exclusive": return boolean.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
         case "messageconverter":
         case "messageConverter": return org.springframework.amqp.support.converter.MessageConverter.class;
         case "messagepropertiesconverter":
         case "messagePropertiesConverter": return org.apache.camel.component.springrabbit.MessagePropertiesConverter.class;
+        case "nolocal":
+        case "noLocal": return boolean.class;
         case "queues": return java.lang.String.class;
         case "replytimeout":
         case "replyTimeout": return long.class;
@@ -111,7 +120,6 @@ public class RabbitMQEndpointConfigurer extends PropertyConfigurerSupport implem
         case "synchronous": return boolean.class;
         case "testconnectiononstartup":
         case "testConnectionOnStartup": return boolean.class;
-        case "transacted": return boolean.class;
         default: return null;
         }
     }
@@ -120,6 +128,8 @@ public class RabbitMQEndpointConfigurer extends PropertyConfigurerSupport implem
     public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
         RabbitMQEndpoint target = (RabbitMQEndpoint) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "acknowledgemode":
+        case "acknowledgeMode": return target.getAcknowledgeMode();
         case "args": return target.getArgs();
         case "asyncconsumer":
         case "asyncConsumer": return target.isAsyncConsumer();
@@ -147,12 +157,15 @@ public class RabbitMQEndpointConfigurer extends PropertyConfigurerSupport implem
         case "exchangePattern": return target.getExchangePattern();
         case "exchangetype":
         case "exchangeType": return target.getExchangeType();
+        case "exclusive": return target.isExclusive();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
         case "messageconverter":
         case "messageConverter": return target.getMessageConverter();
         case "messagepropertiesconverter":
         case "messagePropertiesConverter": return target.getMessagePropertiesConverter();
+        case "nolocal":
+        case "noLocal": return target.isNoLocal();
         case "queues": return target.getQueues();
         case "replytimeout":
         case "replyTimeout": return target.getReplyTimeout();
@@ -161,7 +174,6 @@ public class RabbitMQEndpointConfigurer extends PropertyConfigurerSupport implem
         case "synchronous": return target.isSynchronous();
         case "testconnectiononstartup":
         case "testConnectionOnStartup": return target.isTestConnectionOnStartup();
-        case "transacted": return target.isTransacted();
         default: return null;
         }
     }
diff --git a/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQEndpointUriFactory.java b/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQEndpointUriFactory.java
index 6707b6f..8bc18ee 100644
--- a/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQEndpointUriFactory.java
+++ b/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQEndpointUriFactory.java
@@ -20,26 +20,28 @@ public class RabbitMQEndpointUriFactory extends org.apache.camel.support.compone
     private static final Set<String> PROPERTY_NAMES;
     private static final Set<String> SECRET_PROPERTY_NAMES;
     static {
-        Set<String> props = new HashSet<>(24);
-        props.add("disableReplyTo");
+        Set<String> props = new HashSet<>(26);
         props.add("asyncConsumer");
-        props.add("deadLetterExchange");
         props.add("synchronous");
-        props.add("exchangePattern");
         props.add("messageConverter");
         props.add("exchangeType");
-        props.add("transacted");
-        props.add("deadLetterExchangeType");
         props.add("autoStartup");
+        props.add("noLocal");
+        props.add("bridgeErrorHandler");
+        props.add("deadLetterRoutingKey");
+        props.add("messagePropertiesConverter");
+        props.add("exclusive");
+        props.add("disableReplyTo");
+        props.add("deadLetterExchange");
+        props.add("exchangePattern");
+        props.add("deadLetterExchangeType");
         props.add("args");
         props.add("lazyStartProducer");
-        props.add("bridgeErrorHandler");
         props.add("deadLetterQueue");
-        props.add("deadLetterRoutingKey");
         props.add("connectionFactory");
         props.add("testConnectionOnStartup");
+        props.add("acknowledgeMode");
         props.add("queues");
-        props.add("messagePropertiesConverter");
         props.add("exchangeName");
         props.add("replyTimeout");
         props.add("exceptionHandler");
diff --git a/components/camel-spring-rabbitmq/src/generated/resources/org/apache/camel/component/springrabbit/spring-rabbitmq.json b/components/camel-spring-rabbitmq/src/generated/resources/org/apache/camel/component/springrabbit/spring-rabbitmq.json
index 6eed0e3..83c6251 100644
--- a/components/camel-spring-rabbitmq/src/generated/resources/org/apache/camel/component/springrabbit/spring-rabbitmq.json
+++ b/components/camel-spring-rabbitmq/src/generated/resources/org/apache/camel/component/springrabbit/spring-rabbitmq.json
@@ -47,6 +47,7 @@
     "disableReplyTo": { "kind": "parameter", "displayName": "Disable Reply To", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Specifies whether Camel ignores the ReplyTo header in messages. If true, Camel does not send a reply back to the destination specified in the ReplyTo header. You can use this option if you want Camel to consume from a rout [...]
     "routingKey": { "kind": "parameter", "displayName": "Routing Key", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Routing key." },
     "testConnectionOnStartup": { "kind": "parameter", "displayName": "Test Connection On Startup", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Specifies whether to test the connection on startup. This ensures that when Camel starts that all the JMS consumers have a valid connection to the JMS broker. If a connection cannot be granted then Camel [...]
+    "acknowledgeMode": { "kind": "parameter", "displayName": "Acknowledge Mode", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "org.springframework.amqp.core.AcknowledgeMode", "enum": [ "NONE", "MANUAL", "AUTO" ], "deprecated": false, "autowired": false, "secret": false, "description": "Flag controlling the behaviour of the container with respect to message acknowledgement. The most common usage is to let the container handle the acknowledgeme [...]
     "asyncConsumer": { "kind": "parameter", "displayName": "Async Consumer", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the consumer processes the Exchange asynchronously. If enabled then the consumer may pickup the next message from the queue, while the previous message is being processed asynchronously (by the Asynchronous  [...]
     "autoDeclare": { "kind": "parameter", "displayName": "Auto Declare", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Specifies whether the consumer should auto declare binding between exchange, queue and routing key when starting." },
     "autoStartup": { "kind": "parameter", "displayName": "Auto Startup", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Specifies whether the consumer container should auto-startup." },
@@ -56,6 +57,8 @@
     "deadLetterQueue": { "kind": "parameter", "displayName": "Dead Letter Queue", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the dead letter queue" },
     "deadLetterRoutingKey": { "kind": "parameter", "displayName": "Dead Letter Routing Key", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The routing key for the dead letter exchange" },
     "exchangeType": { "kind": "parameter", "displayName": "Exchange Type", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "direct", "fanout", "headers", "topic" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "direct", "description": "The type of the exchange" },
+    "exclusive": { "kind": "parameter", "displayName": "Exclusive", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Set to true for an exclusive consumer" },
+    "noLocal": { "kind": "parameter", "displayName": "No Local", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Set to true for an no-local consumer" },
     "queues": { "kind": "parameter", "displayName": "Queues", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The queue(s) to use for consuming messages. Multiple queue names can be separated by comma." },
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the con [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", "InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
@@ -64,7 +67,6 @@
     "args": { "kind": "parameter", "displayName": "Args", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "prefix": "arg.", "multiValue": true, "deprecated": false, "autowired": false, "secret": false, "description": "Specify arguments for configuring the different RabbitMQ concepts, a different prefix is required for each element: arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dl [...]
     "messageConverter": { "kind": "parameter", "displayName": "Message Converter", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.springframework.amqp.support.converter.MessageConverter", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom MessageConverter so you can be in control how to map to\/from a org.springframework.amqp.core.Message." },
     "messagePropertiesConverter": { "kind": "parameter", "displayName": "Message Properties Converter", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.springrabbit.MessagePropertiesConverter", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom MessagePropertiesConverter so you can be in control how to map to\/from a org.springframework.amqp.core.MessageProperties." },
-    "synchronous": { "kind": "parameter", "displayName": "Synchronous", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported)." },
-    "transacted": { "kind": "parameter", "displayName": "Transacted", "group": "transaction", "label": "transaction", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Specifies whether to use transacted mode" }
+    "synchronous": { "kind": "parameter", "displayName": "Synchronous", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported)." }
   }
 }
diff --git a/components/camel-spring-rabbitmq/src/main/docs/spring-rabbitmq-component.adoc b/components/camel-spring-rabbitmq/src/main/docs/spring-rabbitmq-component.adoc
index 04b35cf..16fa6d5 100644
--- a/components/camel-spring-rabbitmq/src/main/docs/spring-rabbitmq-component.adoc
+++ b/components/camel-spring-rabbitmq/src/main/docs/spring-rabbitmq-component.adoc
@@ -91,7 +91,7 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (23 parameters):
+=== Query Parameters (25 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -101,6 +101,7 @@ with the following path and query parameters:
 | *disableReplyTo* (common) | Specifies whether Camel ignores the ReplyTo header in messages. If true, Camel does not send a reply back to the destination specified in the ReplyTo header. You can use this option if you want Camel to consume from a route and you do not want Camel to automatically send back a reply message because another component in your code handles the reply message. You can also use this option if you want to use Camel as a proxy between different message brokers and  [...]
 | *routingKey* (common) | Routing key. |  | String
 | *testConnectionOnStartup* (common) | Specifies whether to test the connection on startup. This ensures that when Camel starts that all the JMS consumers have a valid connection to the JMS broker. If a connection cannot be granted then Camel throws an exception on startup. This ensures that Camel is not started with failed connections. The JMS producers is tested as well. | false | boolean
+| *acknowledgeMode* (consumer) | Flag controlling the behaviour of the container with respect to message acknowledgement. The most common usage is to let the container handle the acknowledgements (so the listener doesn't need to know about the channel or the message). Set to AcknowledgeMode.MANUAL if the listener will send the acknowledgements itself using Channel.basicAck(long, boolean). Manual acks are consistent with either a transactional or non-transactional channel, but if you are  [...]
 | *asyncConsumer* (consumer) | Whether the consumer processes the Exchange asynchronously. If enabled then the consumer may pickup the next message from the queue, while the previous message is being processed asynchronously (by the Asynchronous Routing Engine). This means that messages may be processed not 100% strictly in order. If disabled (as default) then the Exchange is fully processed before the consumer will pickup the next message from the queue. | false | boolean
 | *autoDeclare* (consumer) | Specifies whether the consumer should auto declare binding between exchange, queue and routing key when starting. | true | boolean
 | *autoStartup* (consumer) | Specifies whether the consumer container should auto-startup. | true | boolean
@@ -110,6 +111,8 @@ with the following path and query parameters:
 | *deadLetterQueue* (consumer) | The name of the dead letter queue |  | String
 | *deadLetterRoutingKey* (consumer) | The routing key for the dead letter exchange |  | String
 | *exchangeType* (consumer) | The type of the exchange. There are 4 enums and the value can be one of: direct, fanout, headers, topic | direct | String
+| *exclusive* (consumer) | Set to true for an exclusive consumer | false | boolean
+| *noLocal* (consumer) | Set to true for an no-local consumer | false | boolean
 | *queues* (consumer) | The queue(s) to use for consuming messages. Multiple queue names can be separated by comma. |  | String
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
@@ -119,7 +122,6 @@ with the following path and query parameters:
 | *messageConverter* (advanced) | To use a custom MessageConverter so you can be in control how to map to/from a org.springframework.amqp.core.Message. |  | MessageConverter
 | *messagePropertiesConverter* (advanced) | To use a custom MessagePropertiesConverter so you can be in control how to map to/from a org.springframework.amqp.core.MessageProperties. |  | MessagePropertiesConverter
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
-| *transacted* (transaction) | Specifies whether to use transacted mode | false | boolean
 |===
 // endpoint options: END
 
diff --git a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/DefaultListenerContainerFactory.java b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/DefaultListenerContainerFactory.java
index 94daa91..1566cc6 100644
--- a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/DefaultListenerContainerFactory.java
+++ b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/DefaultListenerContainerFactory.java
@@ -20,6 +20,9 @@ import org.springframework.amqp.core.AmqpAdmin;
 import org.springframework.amqp.rabbit.core.RabbitAdmin;
 import org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer;
 
+/**
+ * Default {@link ListenerContainerFactory}.
+ */
 public class DefaultListenerContainerFactory implements ListenerContainerFactory {
 
     @Override
@@ -28,6 +31,9 @@ public class DefaultListenerContainerFactory implements ListenerContainerFactory
         if (endpoint.getQueues() != null) {
             listener.setQueueNames(endpoint.getQueues().split(","));
         }
+        listener.setAcknowledgeMode(endpoint.getAcknowledgeMode());
+        listener.setExclusive(endpoint.isExclusive());
+        listener.setNoLocal(endpoint.isNoLocal());
 
         AmqpAdmin admin = endpoint.getComponent().getAmqpAdmin();
         if (endpoint.isAutoDeclare() && admin == null) {
@@ -42,4 +48,5 @@ public class DefaultListenerContainerFactory implements ListenerContainerFactory
         listener.setShutdownTimeout(endpoint.getComponent().getShutdownTimeout());
         return listener;
     }
+
 }
diff --git a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/EndpointMessageListener.java b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/EndpointMessageListener.java
index c43344c..ed15da2 100644
--- a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/EndpointMessageListener.java
+++ b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/EndpointMessageListener.java
@@ -105,7 +105,7 @@ public class EndpointMessageListener implements ChannelAwareMessageListener {
             // (eg to not consume the next message before the previous has been fully processed)
             // but if end user explicit configure consumerAsync=true, then we can process the message
             // asynchronously (unless endpoint has been configured synchronous, or we use transaction)
-            boolean forceSync = endpoint.isSynchronous() || endpoint.isTransacted();
+            boolean forceSync = endpoint.isSynchronous();
             if (forceSync || !isAsync()) {
                 // must process synchronous if transacted or configured to do so
                 if (LOG.isTraceEnabled()) {
diff --git a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQEndpoint.java b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQEndpoint.java
index b3d5b60..f573e77 100644
--- a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQEndpoint.java
+++ b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQEndpoint.java
@@ -33,6 +33,7 @@ import org.apache.camel.support.DefaultEndpoint;
 import org.apache.camel.util.PropertiesHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.amqp.core.AcknowledgeMode;
 import org.springframework.amqp.core.AmqpAdmin;
 import org.springframework.amqp.core.Binding;
 import org.springframework.amqp.core.ExchangeBuilder;
@@ -93,10 +94,6 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
     private boolean asyncConsumer;
     @UriParam(label = "common", description = "Routing key.")
     private String routingKey;
-    // Transaction related configuration
-    @UriParam(label = "transaction",
-              description = "Specifies whether to use transacted mode")
-    private boolean transacted;
     @UriParam(description = "Specifies whether to test the connection on startup."
                             + " This ensures that when Camel starts that all the JMS consumers have a valid connection to the JMS broker."
                             + " If a connection cannot be granted then Camel throws an exception on startup."
@@ -114,6 +111,18 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
                             + " arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue. arg.dlq.binding."
                             + " For example to declare a queue with message ttl argument: args=arg.queue.x-message-ttl=60000")
     private Map<String, Object> args;
+    @UriParam(label = "consumer",
+              description = "Flag controlling the behaviour of the container with respect to message acknowledgement. The most common usage is to let the container handle the acknowledgements"
+                            + " (so the listener doesn't need to know about the channel or the message)."
+                            + " Set to AcknowledgeMode.MANUAL if the listener will send the acknowledgements itself using Channel.basicAck(long, boolean). Manual acks are consistent with either a transactional or non-transactional channel,"
+                            + " but if you are doing no other work on the channel at the same other than receiving a single message then the transaction is probably unnecessary."
+                            + " Set to AcknowledgeMode.NONE to tell the broker not to expect any acknowledgements, and it will assume all messages are acknowledged as soon as they are sent (this is autoack in native Rabbit broker terms)."
+                            + " If AcknowledgeMode.NONE then the channel cannot be transactional (so the container will fail on start up if that flag is accidentally set).")
+    private AcknowledgeMode acknowledgeMode = AcknowledgeMode.AUTO;
+    @UriParam(label = "consumer", description = "Set to true for an exclusive consumer")
+    private boolean exclusive;
+    @UriParam(label = "consumer", description = "Set to true for an no-local consumer")
+    private boolean noLocal;
     @UriParam(label = "consumer", description = "The name of the dead letter exchange")
     private String deadLetterExchange;
     @UriParam(label = "consumer", description = "The name of the dead letter queue")
@@ -164,14 +173,6 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
         this.queues = queues;
     }
 
-    public boolean isTransacted() {
-        return transacted;
-    }
-
-    public void setTransacted(boolean transacted) {
-        this.transacted = transacted;
-    }
-
     public boolean isAutoStartup() {
         return autoStartup;
     }
@@ -244,6 +245,30 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
         this.args = args;
     }
 
+    public AcknowledgeMode getAcknowledgeMode() {
+        return acknowledgeMode;
+    }
+
+    public void setAcknowledgeMode(AcknowledgeMode acknowledgeMode) {
+        this.acknowledgeMode = acknowledgeMode;
+    }
+
+    public boolean isExclusive() {
+        return exclusive;
+    }
+
+    public void setExclusive(boolean exclusive) {
+        this.exclusive = exclusive;
+    }
+
+    public boolean isNoLocal() {
+        return noLocal;
+    }
+
+    public void setNoLocal(boolean noLocal) {
+        this.noLocal = noLocal;
+    }
+
     public String getDeadLetterExchange() {
         return deadLetterExchange;
     }
diff --git a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/RabbitMQEndpointBuilderFactory.java b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/RabbitMQEndpointBuilderFactory.java
index eb19436..f5361a3 100644
--- a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/RabbitMQEndpointBuilderFactory.java
+++ b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/RabbitMQEndpointBuilderFactory.java
@@ -179,6 +179,66 @@ public interface RabbitMQEndpointBuilderFactory {
             return this;
         }
         /**
+         * Flag controlling the behaviour of the container with respect to
+         * message acknowledgement. The most common usage is to let the
+         * container handle the acknowledgements (so the listener doesn't need
+         * to know about the channel or the message). Set to
+         * AcknowledgeMode.MANUAL if the listener will send the acknowledgements
+         * itself using Channel.basicAck(long, boolean). Manual acks are
+         * consistent with either a transactional or non-transactional channel,
+         * but if you are doing no other work on the channel at the same other
+         * than receiving a single message then the transaction is probably
+         * unnecessary. Set to AcknowledgeMode.NONE to tell the broker not to
+         * expect any acknowledgements, and it will assume all messages are
+         * acknowledged as soon as they are sent (this is autoack in native
+         * Rabbit broker terms). If AcknowledgeMode.NONE then the channel cannot
+         * be transactional (so the container will fail on start up if that flag
+         * is accidentally set).
+         * 
+         * The option is a:
+         * &lt;code&gt;org.springframework.amqp.core.AcknowledgeMode&lt;/code&gt; type.
+         * 
+         * Group: consumer
+         * 
+         * @param acknowledgeMode the value to set
+         * @return the dsl builder
+         */
+        default RabbitMQEndpointConsumerBuilder acknowledgeMode(
+                AcknowledgeMode acknowledgeMode) {
+            doSetProperty("acknowledgeMode", acknowledgeMode);
+            return this;
+        }
+        /**
+         * Flag controlling the behaviour of the container with respect to
+         * message acknowledgement. The most common usage is to let the
+         * container handle the acknowledgements (so the listener doesn't need
+         * to know about the channel or the message). Set to
+         * AcknowledgeMode.MANUAL if the listener will send the acknowledgements
+         * itself using Channel.basicAck(long, boolean). Manual acks are
+         * consistent with either a transactional or non-transactional channel,
+         * but if you are doing no other work on the channel at the same other
+         * than receiving a single message then the transaction is probably
+         * unnecessary. Set to AcknowledgeMode.NONE to tell the broker not to
+         * expect any acknowledgements, and it will assume all messages are
+         * acknowledged as soon as they are sent (this is autoack in native
+         * Rabbit broker terms). If AcknowledgeMode.NONE then the channel cannot
+         * be transactional (so the container will fail on start up if that flag
+         * is accidentally set).
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;org.springframework.amqp.core.AcknowledgeMode&lt;/code&gt; type.
+         * 
+         * Group: consumer
+         * 
+         * @param acknowledgeMode the value to set
+         * @return the dsl builder
+         */
+        default RabbitMQEndpointConsumerBuilder acknowledgeMode(
+                String acknowledgeMode) {
+            doSetProperty("acknowledgeMode", acknowledgeMode);
+            return this;
+        }
+        /**
          * Whether the consumer processes the Exchange asynchronously. If
          * enabled then the consumer may pickup the next message from the queue,
          * while the previous message is being processed asynchronously (by the
@@ -409,49 +469,80 @@ public interface RabbitMQEndpointBuilderFactory {
             return this;
         }
         /**
-         * The queue(s) to use for consuming messages. Multiple queue names can
-         * be separated by comma.
+         * Set to true for an exclusive consumer.
          * 
-         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
          * 
+         * Default: false
          * Group: consumer
          * 
-         * @param queues the value to set
+         * @param exclusive the value to set
          * @return the dsl builder
          */
-        default RabbitMQEndpointConsumerBuilder queues(String queues) {
-            doSetProperty("queues", queues);
+        default RabbitMQEndpointConsumerBuilder exclusive(boolean exclusive) {
+            doSetProperty("exclusive", exclusive);
+            return this;
+        }
+        /**
+         * Set to true for an exclusive consumer.
+         * 
+         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
+         * type.
+         * 
+         * Default: false
+         * Group: consumer
+         * 
+         * @param exclusive the value to set
+         * @return the dsl builder
+         */
+        default RabbitMQEndpointConsumerBuilder exclusive(String exclusive) {
+            doSetProperty("exclusive", exclusive);
             return this;
         }
         /**
-         * Specifies whether to use transacted mode.
+         * Set to true for an no-local consumer.
          * 
          * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
          * 
          * Default: false
-         * Group: transaction
+         * Group: consumer
          * 
-         * @param transacted the value to set
+         * @param noLocal the value to set
          * @return the dsl builder
          */
-        default RabbitMQEndpointConsumerBuilder transacted(boolean transacted) {
-            doSetProperty("transacted", transacted);
+        default RabbitMQEndpointConsumerBuilder noLocal(boolean noLocal) {
+            doSetProperty("noLocal", noLocal);
             return this;
         }
         /**
-         * Specifies whether to use transacted mode.
+         * Set to true for an no-local consumer.
          * 
          * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
          * type.
          * 
          * Default: false
-         * Group: transaction
+         * Group: consumer
          * 
-         * @param transacted the value to set
+         * @param noLocal the value to set
          * @return the dsl builder
          */
-        default RabbitMQEndpointConsumerBuilder transacted(String transacted) {
-            doSetProperty("transacted", transacted);
+        default RabbitMQEndpointConsumerBuilder noLocal(String noLocal) {
+            doSetProperty("noLocal", noLocal);
+            return this;
+        }
+        /**
+         * The queue(s) to use for consuming messages. Multiple queue names can
+         * be separated by comma.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: consumer
+         * 
+         * @param queues the value to set
+         * @return the dsl builder
+         */
+        default RabbitMQEndpointConsumerBuilder queues(String queues) {
+            doSetProperty("queues", queues);
             return this;
         }
     }
@@ -916,37 +1007,6 @@ public interface RabbitMQEndpointBuilderFactory {
             doSetProperty("replyTimeout", replyTimeout);
             return this;
         }
-        /**
-         * Specifies whether to use transacted mode.
-         * 
-         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
-         * 
-         * Default: false
-         * Group: transaction
-         * 
-         * @param transacted the value to set
-         * @return the dsl builder
-         */
-        default RabbitMQEndpointProducerBuilder transacted(boolean transacted) {
-            doSetProperty("transacted", transacted);
-            return this;
-        }
-        /**
-         * Specifies whether to use transacted mode.
-         * 
-         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
-         * type.
-         * 
-         * Default: false
-         * Group: transaction
-         * 
-         * @param transacted the value to set
-         * @return the dsl builder
-         */
-        default RabbitMQEndpointProducerBuilder transacted(String transacted) {
-            doSetProperty("transacted", transacted);
-            return this;
-        }
     }
 
     /**
@@ -1255,37 +1315,6 @@ public interface RabbitMQEndpointBuilderFactory {
             doSetProperty("testConnectionOnStartup", testConnectionOnStartup);
             return this;
         }
-        /**
-         * Specifies whether to use transacted mode.
-         * 
-         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
-         * 
-         * Default: false
-         * Group: transaction
-         * 
-         * @param transacted the value to set
-         * @return the dsl builder
-         */
-        default RabbitMQEndpointBuilder transacted(boolean transacted) {
-            doSetProperty("transacted", transacted);
-            return this;
-        }
-        /**
-         * Specifies whether to use transacted mode.
-         * 
-         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
-         * type.
-         * 
-         * Default: false
-         * Group: transaction
-         * 
-         * @param transacted the value to set
-         * @return the dsl builder
-         */
-        default RabbitMQEndpointBuilder transacted(String transacted) {
-            doSetProperty("transacted", transacted);
-            return this;
-        }
     }
 
     /**
@@ -1446,6 +1475,16 @@ public interface RabbitMQEndpointBuilderFactory {
         }
     }
 
+    /**
+     * Proxy enum for <code>org.springframework.amqp.core.AcknowledgeMode</code>
+     * enum.
+     */
+    enum AcknowledgeMode {
+        NONE,
+        MANUAL,
+        AUTO;
+    }
+
     public interface RabbitMQBuilders {
         /**
          * Spring RabbitMQ (camel-spring-rabbitmq)
diff --git a/docs/components/modules/ROOT/pages/spring-rabbitmq-component.adoc b/docs/components/modules/ROOT/pages/spring-rabbitmq-component.adoc
index 1f36e4a..614144a 100644
--- a/docs/components/modules/ROOT/pages/spring-rabbitmq-component.adoc
+++ b/docs/components/modules/ROOT/pages/spring-rabbitmq-component.adoc
@@ -93,7 +93,7 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (23 parameters):
+=== Query Parameters (25 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -103,6 +103,7 @@ with the following path and query parameters:
 | *disableReplyTo* (common) | Specifies whether Camel ignores the ReplyTo header in messages. If true, Camel does not send a reply back to the destination specified in the ReplyTo header. You can use this option if you want Camel to consume from a route and you do not want Camel to automatically send back a reply message because another component in your code handles the reply message. You can also use this option if you want to use Camel as a proxy between different message brokers and  [...]
 | *routingKey* (common) | Routing key. |  | String
 | *testConnectionOnStartup* (common) | Specifies whether to test the connection on startup. This ensures that when Camel starts that all the JMS consumers have a valid connection to the JMS broker. If a connection cannot be granted then Camel throws an exception on startup. This ensures that Camel is not started with failed connections. The JMS producers is tested as well. | false | boolean
+| *acknowledgeMode* (consumer) | Flag controlling the behaviour of the container with respect to message acknowledgement. The most common usage is to let the container handle the acknowledgements (so the listener doesn't need to know about the channel or the message). Set to AcknowledgeMode.MANUAL if the listener will send the acknowledgements itself using Channel.basicAck(long, boolean). Manual acks are consistent with either a transactional or non-transactional channel, but if you are  [...]
 | *asyncConsumer* (consumer) | Whether the consumer processes the Exchange asynchronously. If enabled then the consumer may pickup the next message from the queue, while the previous message is being processed asynchronously (by the Asynchronous Routing Engine). This means that messages may be processed not 100% strictly in order. If disabled (as default) then the Exchange is fully processed before the consumer will pickup the next message from the queue. | false | boolean
 | *autoDeclare* (consumer) | Specifies whether the consumer should auto declare binding between exchange, queue and routing key when starting. | true | boolean
 | *autoStartup* (consumer) | Specifies whether the consumer container should auto-startup. | true | boolean
@@ -112,6 +113,8 @@ with the following path and query parameters:
 | *deadLetterQueue* (consumer) | The name of the dead letter queue |  | String
 | *deadLetterRoutingKey* (consumer) | The routing key for the dead letter exchange |  | String
 | *exchangeType* (consumer) | The type of the exchange. There are 4 enums and the value can be one of: direct, fanout, headers, topic | direct | String
+| *exclusive* (consumer) | Set to true for an exclusive consumer | false | boolean
+| *noLocal* (consumer) | Set to true for an no-local consumer | false | boolean
 | *queues* (consumer) | The queue(s) to use for consuming messages. Multiple queue names can be separated by comma. |  | String
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
@@ -121,7 +124,6 @@ with the following path and query parameters:
 | *messageConverter* (advanced) | To use a custom MessageConverter so you can be in control how to map to/from a org.springframework.amqp.core.Message. |  | MessageConverter
 | *messagePropertiesConverter* (advanced) | To use a custom MessagePropertiesConverter so you can be in control how to map to/from a org.springframework.amqp.core.MessageProperties. |  | MessagePropertiesConverter
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
-| *transacted* (transaction) | Specifies whether to use transacted mode | false | boolean
 |===
 // endpoint options: END
 


[camel] 02/02: CAMEL-16003: camel-spring-rabbitmq - New component using spring client

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch rabbitmq
in repository https://gitbox.apache.org/repos/asf/camel.git

commit b90c9b34a092bcbb0e8a5cb42d16fa63fd2bbfb0
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jan 12 10:13:49 2021 +0100

    CAMEL-16003: camel-spring-rabbitmq - New component using spring client
---
 .../catalog/docs/spring-rabbitmq-component.adoc    | 114 +++++-
 .../springrabbit/RabbitMQComponentConfigurer.java  |   6 +
 .../component/springrabbit/spring-rabbitmq.json    |   3 +-
 .../src/main/docs/spring-rabbitmq-component.adoc   | 114 +++++-
 .../DefaultListenerContainerFactory.java           |   1 +
 .../component/springrabbit/RabbitMQComponent.java  |  12 +
 .../component/springrabbit/RabbitMQConstants.java  |  46 +--
 .../component/springrabbit/RabbitMQEndpoint.java   |  65 ++--
 .../springrabbit/RabbitMQMessageConverter.java     | 410 ---------------------
 .../src/test/resources/log4j2.properties           |   6 +-
 .../dsl/SpringRabbitmqComponentBuilderFactory.java |  17 +
 .../dsl/RabbitMQEndpointBuilderFactory.java        |  48 +--
 .../ROOT/pages/spring-rabbitmq-component.adoc      | 114 +++++-
 13 files changed, 428 insertions(+), 528 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-rabbitmq-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-rabbitmq-component.adoc
index 16fa6d5..cf46109 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-rabbitmq-component.adoc
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-rabbitmq-component.adoc
@@ -43,7 +43,7 @@ determines the exchange the queue will be bound to.
 == Options
 
 // component options: START
-The Spring RabbitMQ component supports 18 options, which are listed below.
+The Spring RabbitMQ component supports 19 options, which are listed below.
 
 
 
@@ -53,6 +53,7 @@ The Spring RabbitMQ component supports 18 options, which are listed below.
 | *amqpAdmin* (common) | *Autowired* Optional AMQP Admin service to use for auto declaring elements (queues, exchanges, bindings) |  | AmqpAdmin
 | *connectionFactory* (common) | *Autowired* The connection factory to be use. A connection factory must be configured either on the component or endpoint. |  | ConnectionFactory
 | *testConnectionOnStartup* (common) | Specifies whether to test the connection on startup. This ensures that when Camel starts that all the JMS consumers have a valid connection to the JMS broker. If a connection cannot be granted then Camel throws an exception on startup. This ensures that Camel is not started with failed connections. The JMS producers is tested as well. | false | boolean
+| *autoDeclare* (consumer) | Specifies whether the consumer should auto declare binding between exchange, queue and routing key when starting. | true | boolean
 | *autoStartup* (consumer) | Specifies whether the consumer container should auto-startup. | true | boolean
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
 | *deadLetterExchange* (consumer) | The name of the dead letter exchange |  | String
@@ -118,7 +119,7 @@ with the following path and query parameters:
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
 | *replyTimeout* (producer) | Specify the timeout in milliseconds to be used when waiting for a reply message when doing request/reply messaging. The default value is 5 seconds. A negative value indicates an indefinite timeout. | 5000 | long
-| *args* (advanced) | Specify arguments for configuring the different RabbitMQ concepts, a different prefix is required for each element: arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue. arg.dlq.binding. For example to declare a queue with message ttl argument: args=arg.queue.x-message-ttl=60000 |  | Map
+| *args* (advanced) | Specify arguments for configuring the different RabbitMQ concepts, a different prefix is required for each element: arg.consumer. arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue. arg.dlq.binding. For example to declare a queue with message ttl argument: args=arg.queue.x-message-ttl=60000 |  | Map
 | *messageConverter* (advanced) | To use a custom MessageConverter so you can be in control how to map to/from a org.springframework.amqp.core.Message. |  | MessageConverter
 | *messagePropertiesConverter* (advanced) | To use a custom MessagePropertiesConverter so you can be in control how to map to/from a org.springframework.amqp.core.MessageProperties. |  | MessagePropertiesConverter
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
@@ -129,13 +130,12 @@ with the following path and query parameters:
 
 To connect to RabbitMQ you need to setup a `ConnectionFactory` (same as with JMS) with the login details such as:
 
+TIP: It is recommended to use `CachingConnectionFactory` from spring-rabbit as it comes with connection pooling out of the box.
+
 [source,xml]
 ----
-<bean id="rabbitConnectionFactory" class="com.rabbitmq.client.ConnectionFactory">
-  <property name="host" value="localhost"/>
-  <property name="port" value="5672"/>
-  <property name="username" value="camel"/>
-  <property name="password" value="bugsbunny"/>
+<bean id="rabbitConnectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
+  <property name="uri" value="amqp://lolcalhost:5672"/>
 </bean>
 ----
 
@@ -145,11 +145,107 @@ The `ConnectionFactory` is auto-detected by default, so you can just do
 ----
 <camelContext>
   <route>
-    <from uri="direct:rabbitMQEx2"/>
-    <to uri="spring-rabbitmq:ex2"/>
+    <from uri="direct:cheese"/>
+    <to uri="spring-rabbitmq:foo?routingKey=cheese"/>
   </route>
 </camelContext>
 ----
 
+== Request / Reply
+
+Request and reply messaging is supported using https://www.rabbitmq.com/direct-reply-to.html[RabbitMQ direct reply-to].
+
+The example below will do request/reply, where the message is sent via the cheese exchange name and routing key _foo.bar_,
+which is being consumed by the 2nd Camel route, that prepends the message with `Hello `, and then sends back the message.
+
+So if we send `World` as message body to _direct:start_ then, we will se the message being logged
+
+- log:request => World
+- log:input => World
+- log:response => Hello World
+
+[source,java]
+----
+from("direct:start")
+    .to("log:request")
+    .to(ExchangePattern.InOut, "spring-rabbitmq:cheese?routingKey=foo.bar")
+    .to("log:response");
+
+from("spring-rabbitmq:cheese?queues=myqueue&routingKey=foo.bar")
+    .to("log:input")
+    .transform(body().prepend("Hello "));
+----
+
+The Spring RabbitMQ will automatic nessasary declare the elements and setup the binding between the exchange, queue and routing keys.
+This can be turned off by setting `autoDeclare=false`.
+
+== Reuse endpoint and send to different destinations computed at runtime
+
+If you need to send messages to a lot of different RabbitMQ exchanges, it
+makes sense to reuse a endpoint and specify the real destination in
+a message header. This allows Camel to reuse the same endpoint, but send
+to different exchanges. This greatly reduces the number of endpoints
+created and economizes on memory and thread resources.
+
+TIP: Using xref:{eip-vc}:eips:toD-eip.adoc[toD] is easier than specifying the dynamic destination with headers
+
+You can specify using the following headers:
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=====================================================================
+|Header |Type |Description
+|`CamelRabbitmqExchangeOverrideName` |`String` |The exchange name.
+|`CamelRabbitmqRoutingOverrideKey` |`String` |The routing key.
+|=====================================================================
+
+For example, the following route shows how you can compute a destination
+at run time and use it to override the exchange appearing in the endpoint
+URL:
+
+[source,java]
+----
+from("file://inbox")
+  .to("bean:computeDestination")
+  .to("spring-rabbitmq:dummy");
+----
+
+The exchange name, `dummy`, is just a placeholder. It must be provided as
+part of the RabbitMQ endpoint URL, but it will be ignored in this example.
+
+In the `computeDestination` bean, specify the real destination by
+setting the `CamelRabbitmqExchangeOverrideName` header as follows:
+
+[source,java]
+----
+public void setExchangeHeader(Exchange exchange) {
+   String region = ....
+   exchange.getIn().setHeader("CamelRabbitmqExchangeOverrideName", "order-" + region);
+}
+----
+
+Then Camel will read this header and use it as the exchange name instead
+of the one configured on the endpoint. So, in this example Camel sends
+the message to `spring-rabbitmq:order-emea`, assuming the `region` value was `emea`.
+
+Keep in mind that the producer removes both `CamelRabbitmqExchangeOverrideName` and `CamelRabbitmqRoutingOverrideKey`
+headers from the exchange and do not propagate them to the created Rabbitmq
+message in order to avoid the accidental loops
+in the routes (in scenarios when the message will be forwarded to the
+another RabbitMQ endpoint).
+
+== Using toD
+
+If you need to send messages to a lot of different exchanges, it
+makes sense to reuse a endpoint and specify the dynamic destinations
+with simple language using xref:{eip-vc}:eips:toD-eip.adoc[toD].
+
+For example suppose you need to send messages to exchanges with order types,
+then using toD could for example be done as follows:
+
+[source,java]
+----
+from("direct:order")
+  .toD("spring-rabbit:order-${header.orderType}");
+----
 
 include::camel-spring-boot::page$rabbitmq-starter.adoc[]
diff --git a/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQComponentConfigurer.java b/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQComponentConfigurer.java
index 0e48117..b4724f5 100644
--- a/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQComponentConfigurer.java
+++ b/components/camel-spring-rabbitmq/src/generated/java/org/apache/camel/component/springrabbit/RabbitMQComponentConfigurer.java
@@ -23,6 +23,8 @@ public class RabbitMQComponentConfigurer extends PropertyConfigurerSupport imple
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "amqpadmin":
         case "amqpAdmin": target.setAmqpAdmin(property(camelContext, org.springframework.amqp.core.AmqpAdmin.class, value)); return true;
+        case "autodeclare":
+        case "autoDeclare": target.setAutoDeclare(property(camelContext, boolean.class, value)); return true;
         case "autostartup":
         case "autoStartup": target.setAutoStartup(property(camelContext, boolean.class, value)); return true;
         case "autowiredenabled":
@@ -71,6 +73,8 @@ public class RabbitMQComponentConfigurer extends PropertyConfigurerSupport imple
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "amqpadmin":
         case "amqpAdmin": return org.springframework.amqp.core.AmqpAdmin.class;
+        case "autodeclare":
+        case "autoDeclare": return boolean.class;
         case "autostartup":
         case "autoStartup": return boolean.class;
         case "autowiredenabled":
@@ -115,6 +119,8 @@ public class RabbitMQComponentConfigurer extends PropertyConfigurerSupport imple
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "amqpadmin":
         case "amqpAdmin": return target.getAmqpAdmin();
+        case "autodeclare":
+        case "autoDeclare": return target.isAutoDeclare();
         case "autostartup":
         case "autoStartup": return target.isAutoStartup();
         case "autowiredenabled":
diff --git a/components/camel-spring-rabbitmq/src/generated/resources/org/apache/camel/component/springrabbit/spring-rabbitmq.json b/components/camel-spring-rabbitmq/src/generated/resources/org/apache/camel/component/springrabbit/spring-rabbitmq.json
index 83c6251..d5c19b7 100644
--- a/components/camel-spring-rabbitmq/src/generated/resources/org/apache/camel/component/springrabbit/spring-rabbitmq.json
+++ b/components/camel-spring-rabbitmq/src/generated/resources/org/apache/camel/component/springrabbit/spring-rabbitmq.json
@@ -25,6 +25,7 @@
     "amqpAdmin": { "kind": "property", "displayName": "Amqp Admin", "group": "common", "label": "", "required": false, "type": "object", "javaType": "org.springframework.amqp.core.AmqpAdmin", "deprecated": false, "autowired": true, "secret": false, "description": "Optional AMQP Admin service to use for auto declaring elements (queues, exchanges, bindings)" },
     "connectionFactory": { "kind": "property", "displayName": "Connection Factory", "group": "common", "label": "", "required": false, "type": "object", "javaType": "org.springframework.amqp.rabbit.connection.ConnectionFactory", "deprecated": false, "autowired": true, "secret": false, "description": "The connection factory to be use. A connection factory must be configured either on the component or endpoint." },
     "testConnectionOnStartup": { "kind": "property", "displayName": "Test Connection On Startup", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Specifies whether to test the connection on startup. This ensures that when Camel starts that all the JMS consumers have a valid connection to the JMS broker. If a connection cannot be granted then Camel  [...]
+    "autoDeclare": { "kind": "property", "displayName": "Auto Declare", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Specifies whether the consumer should auto declare binding between exchange, queue and routing key when starting." },
     "autoStartup": { "kind": "property", "displayName": "Auto Startup", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Specifies whether the consumer container should auto-startup." },
     "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a me [...]
     "deadLetterExchange": { "kind": "property", "displayName": "Dead Letter Exchange", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the dead letter exchange" },
@@ -64,7 +65,7 @@
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", "InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
     "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during sta [...]
     "replyTimeout": { "kind": "parameter", "displayName": "Reply Timeout", "group": "producer", "label": "producer", "required": false, "type": "duration", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "5000", "description": "Specify the timeout in milliseconds to be used when waiting for a reply message when doing request\/reply messaging. The default value is 5 seconds. A negative value indicates an indefinite timeout." },
-    "args": { "kind": "parameter", "displayName": "Args", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "prefix": "arg.", "multiValue": true, "deprecated": false, "autowired": false, "secret": false, "description": "Specify arguments for configuring the different RabbitMQ concepts, a different prefix is required for each element: arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dl [...]
+    "args": { "kind": "parameter", "displayName": "Args", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "prefix": "arg.", "multiValue": true, "deprecated": false, "autowired": false, "secret": false, "description": "Specify arguments for configuring the different RabbitMQ concepts, a different prefix is required for each element: arg.consumer. arg.exchange. arg.queue. arg.binding. arg.dlq.ex [...]
     "messageConverter": { "kind": "parameter", "displayName": "Message Converter", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.springframework.amqp.support.converter.MessageConverter", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom MessageConverter so you can be in control how to map to\/from a org.springframework.amqp.core.Message." },
     "messagePropertiesConverter": { "kind": "parameter", "displayName": "Message Properties Converter", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.springrabbit.MessagePropertiesConverter", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom MessagePropertiesConverter so you can be in control how to map to\/from a org.springframework.amqp.core.MessageProperties." },
     "synchronous": { "kind": "parameter", "displayName": "Synchronous", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported)." }
diff --git a/components/camel-spring-rabbitmq/src/main/docs/spring-rabbitmq-component.adoc b/components/camel-spring-rabbitmq/src/main/docs/spring-rabbitmq-component.adoc
index 16fa6d5..cf46109 100644
--- a/components/camel-spring-rabbitmq/src/main/docs/spring-rabbitmq-component.adoc
+++ b/components/camel-spring-rabbitmq/src/main/docs/spring-rabbitmq-component.adoc
@@ -43,7 +43,7 @@ determines the exchange the queue will be bound to.
 == Options
 
 // component options: START
-The Spring RabbitMQ component supports 18 options, which are listed below.
+The Spring RabbitMQ component supports 19 options, which are listed below.
 
 
 
@@ -53,6 +53,7 @@ The Spring RabbitMQ component supports 18 options, which are listed below.
 | *amqpAdmin* (common) | *Autowired* Optional AMQP Admin service to use for auto declaring elements (queues, exchanges, bindings) |  | AmqpAdmin
 | *connectionFactory* (common) | *Autowired* The connection factory to be use. A connection factory must be configured either on the component or endpoint. |  | ConnectionFactory
 | *testConnectionOnStartup* (common) | Specifies whether to test the connection on startup. This ensures that when Camel starts that all the JMS consumers have a valid connection to the JMS broker. If a connection cannot be granted then Camel throws an exception on startup. This ensures that Camel is not started with failed connections. The JMS producers is tested as well. | false | boolean
+| *autoDeclare* (consumer) | Specifies whether the consumer should auto declare binding between exchange, queue and routing key when starting. | true | boolean
 | *autoStartup* (consumer) | Specifies whether the consumer container should auto-startup. | true | boolean
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
 | *deadLetterExchange* (consumer) | The name of the dead letter exchange |  | String
@@ -118,7 +119,7 @@ with the following path and query parameters:
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
 | *replyTimeout* (producer) | Specify the timeout in milliseconds to be used when waiting for a reply message when doing request/reply messaging. The default value is 5 seconds. A negative value indicates an indefinite timeout. | 5000 | long
-| *args* (advanced) | Specify arguments for configuring the different RabbitMQ concepts, a different prefix is required for each element: arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue. arg.dlq.binding. For example to declare a queue with message ttl argument: args=arg.queue.x-message-ttl=60000 |  | Map
+| *args* (advanced) | Specify arguments for configuring the different RabbitMQ concepts, a different prefix is required for each element: arg.consumer. arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue. arg.dlq.binding. For example to declare a queue with message ttl argument: args=arg.queue.x-message-ttl=60000 |  | Map
 | *messageConverter* (advanced) | To use a custom MessageConverter so you can be in control how to map to/from a org.springframework.amqp.core.Message. |  | MessageConverter
 | *messagePropertiesConverter* (advanced) | To use a custom MessagePropertiesConverter so you can be in control how to map to/from a org.springframework.amqp.core.MessageProperties. |  | MessagePropertiesConverter
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
@@ -129,13 +130,12 @@ with the following path and query parameters:
 
 To connect to RabbitMQ you need to setup a `ConnectionFactory` (same as with JMS) with the login details such as:
 
+TIP: It is recommended to use `CachingConnectionFactory` from spring-rabbit as it comes with connection pooling out of the box.
+
 [source,xml]
 ----
-<bean id="rabbitConnectionFactory" class="com.rabbitmq.client.ConnectionFactory">
-  <property name="host" value="localhost"/>
-  <property name="port" value="5672"/>
-  <property name="username" value="camel"/>
-  <property name="password" value="bugsbunny"/>
+<bean id="rabbitConnectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
+  <property name="uri" value="amqp://lolcalhost:5672"/>
 </bean>
 ----
 
@@ -145,11 +145,107 @@ The `ConnectionFactory` is auto-detected by default, so you can just do
 ----
 <camelContext>
   <route>
-    <from uri="direct:rabbitMQEx2"/>
-    <to uri="spring-rabbitmq:ex2"/>
+    <from uri="direct:cheese"/>
+    <to uri="spring-rabbitmq:foo?routingKey=cheese"/>
   </route>
 </camelContext>
 ----
 
+== Request / Reply
+
+Request and reply messaging is supported using https://www.rabbitmq.com/direct-reply-to.html[RabbitMQ direct reply-to].
+
+The example below will do request/reply, where the message is sent via the cheese exchange name and routing key _foo.bar_,
+which is being consumed by the 2nd Camel route, that prepends the message with `Hello `, and then sends back the message.
+
+So if we send `World` as message body to _direct:start_ then, we will se the message being logged
+
+- log:request => World
+- log:input => World
+- log:response => Hello World
+
+[source,java]
+----
+from("direct:start")
+    .to("log:request")
+    .to(ExchangePattern.InOut, "spring-rabbitmq:cheese?routingKey=foo.bar")
+    .to("log:response");
+
+from("spring-rabbitmq:cheese?queues=myqueue&routingKey=foo.bar")
+    .to("log:input")
+    .transform(body().prepend("Hello "));
+----
+
+The Spring RabbitMQ will automatic nessasary declare the elements and setup the binding between the exchange, queue and routing keys.
+This can be turned off by setting `autoDeclare=false`.
+
+== Reuse endpoint and send to different destinations computed at runtime
+
+If you need to send messages to a lot of different RabbitMQ exchanges, it
+makes sense to reuse a endpoint and specify the real destination in
+a message header. This allows Camel to reuse the same endpoint, but send
+to different exchanges. This greatly reduces the number of endpoints
+created and economizes on memory and thread resources.
+
+TIP: Using xref:{eip-vc}:eips:toD-eip.adoc[toD] is easier than specifying the dynamic destination with headers
+
+You can specify using the following headers:
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=====================================================================
+|Header |Type |Description
+|`CamelRabbitmqExchangeOverrideName` |`String` |The exchange name.
+|`CamelRabbitmqRoutingOverrideKey` |`String` |The routing key.
+|=====================================================================
+
+For example, the following route shows how you can compute a destination
+at run time and use it to override the exchange appearing in the endpoint
+URL:
+
+[source,java]
+----
+from("file://inbox")
+  .to("bean:computeDestination")
+  .to("spring-rabbitmq:dummy");
+----
+
+The exchange name, `dummy`, is just a placeholder. It must be provided as
+part of the RabbitMQ endpoint URL, but it will be ignored in this example.
+
+In the `computeDestination` bean, specify the real destination by
+setting the `CamelRabbitmqExchangeOverrideName` header as follows:
+
+[source,java]
+----
+public void setExchangeHeader(Exchange exchange) {
+   String region = ....
+   exchange.getIn().setHeader("CamelRabbitmqExchangeOverrideName", "order-" + region);
+}
+----
+
+Then Camel will read this header and use it as the exchange name instead
+of the one configured on the endpoint. So, in this example Camel sends
+the message to `spring-rabbitmq:order-emea`, assuming the `region` value was `emea`.
+
+Keep in mind that the producer removes both `CamelRabbitmqExchangeOverrideName` and `CamelRabbitmqRoutingOverrideKey`
+headers from the exchange and do not propagate them to the created Rabbitmq
+message in order to avoid the accidental loops
+in the routes (in scenarios when the message will be forwarded to the
+another RabbitMQ endpoint).
+
+== Using toD
+
+If you need to send messages to a lot of different exchanges, it
+makes sense to reuse a endpoint and specify the dynamic destinations
+with simple language using xref:{eip-vc}:eips:toD-eip.adoc[toD].
+
+For example suppose you need to send messages to exchanges with order types,
+then using toD could for example be done as follows:
+
+[source,java]
+----
+from("direct:order")
+  .toD("spring-rabbit:order-${header.orderType}");
+----
 
 include::camel-spring-boot::page$rabbitmq-starter.adoc[]
diff --git a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/DefaultListenerContainerFactory.java b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/DefaultListenerContainerFactory.java
index 1566cc6..902fa0d 100644
--- a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/DefaultListenerContainerFactory.java
+++ b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/DefaultListenerContainerFactory.java
@@ -46,6 +46,7 @@ public class DefaultListenerContainerFactory implements ListenerContainerFactory
         }
         listener.setPrefetchCount(endpoint.getComponent().getPrefetchCount());
         listener.setShutdownTimeout(endpoint.getComponent().getShutdownTimeout());
+        listener.setConsumerArguments(endpoint.getConsumerArgs());
         return listener;
     }
 
diff --git a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQComponent.java b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQComponent.java
index 69f9519..ff4975f 100644
--- a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQComponent.java
+++ b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQComponent.java
@@ -49,6 +49,9 @@ public class RabbitMQComponent extends HeaderFilterStrategyComponent {
     @Metadata(label = "consumer", defaultValue = "true",
               description = "Specifies whether the consumer container should auto-startup.")
     private boolean autoStartup = true;
+    @Metadata(label = "consumer", defaultValue = "true",
+              description = "Specifies whether the consumer should auto declare binding between exchange, queue and routing key when starting.")
+    private boolean autoDeclare = true;
     @Metadata(label = "advanced",
               description = "To use a custom MessageConverter so you can be in control how to map to/from a org.springframework.amqp.core.Message.")
     private MessageConverter messageConverter;
@@ -105,6 +108,7 @@ public class RabbitMQComponent extends HeaderFilterStrategyComponent {
         endpoint.setMessageConverter(messageConverter);
         endpoint.setMessagePropertiesConverter(messagePropertiesConverter);
         endpoint.setAutoStartup(autoStartup);
+        endpoint.setAutoDeclare(autoDeclare);
         endpoint.setDeadLetterExchange(deadLetterExchange);
         endpoint.setDeadLetterExchangeType(deadLetterExchangeType);
         endpoint.setDeadLetterQueue(deadLetterQueue);
@@ -163,6 +167,14 @@ public class RabbitMQComponent extends HeaderFilterStrategyComponent {
         this.autoStartup = autoStartup;
     }
 
+    public boolean isAutoDeclare() {
+        return autoDeclare;
+    }
+
+    public void setAutoDeclare(boolean autoDeclare) {
+        this.autoDeclare = autoDeclare;
+    }
+
     public String getDeadLetterExchange() {
         return deadLetterExchange;
     }
diff --git a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQConstants.java b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQConstants.java
index 551bf12..14ad379 100644
--- a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQConstants.java
+++ b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQConstants.java
@@ -16,53 +16,21 @@
  */
 package org.apache.camel.component.springrabbit;
 
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
 public final class RabbitMQConstants {
 
     public static final String DEFAULT_EXCHANGE_NAME = "default";
 
     public static final String CHANNEL = "CamelRabbitmqChannel";
-
-    public static final String ROUTING_KEY = "CamelRabbitmqRoutingKey";
     public static final String ROUTING_OVERRIDE_KEY = "CamelRabbitmqRoutingOverrideKey";
     public static final String EXCHANGE_OVERRIDE_NAME = "CamelRabbitmqExchangeOverrideName";
-    public static final String EXCHANGE_NAME = "CamelRabbitmqExchangeName";
-    public static final String CONTENT_TYPE = "CamelRabbitmqContentType";
-    public static final String PRIORITY = "CamelRabbitmqPriority";
-    public static final String DELIVERY_TAG = "CamelRabbitmqDeliveryTag";
-    public static final String REDELIVERY_TAG = "CamelRabbitmqRedeliveryTag";
-    public static final String CORRELATIONID = "CamelRabbitmqCorrelationId";
-    public static final String MESSAGE_ID = "CamelRabbitmqMessageId";
-    public static final String DELIVERY_MODE = "CamelRabbitmqDeliveryMode";
-    public static final String USERID = "CamelRabbitmqUserId";
-    public static final String CLUSTERID = "CamelRabbitmqClusterId";
-    public static final String REQUEST_TIMEOUT = "CamelRabbitmqRequestTimeout";
-    public static final String REPLY_TO = "CamelRabbitmqReplyTo";
-    public static final String CONTENT_ENCODING = "CamelRabbitmqContentEncoding";
-    public static final String TYPE = "CamelRabbitmqType";
-    public static final String EXPIRATION = "CamelRabbitmqExpiration";
-    public static final String TIMESTAMP = "CamelRabbitmqTimestamp";
-    public static final String APP_ID = "CamelRabbitmqAppId";
-    public static final String REQUEUE = "CamelRabbitmqRequeue";
-    public static final String MANDATORY = "CamelRabbitmqMandatory";
-    public static final String IMMEDIATE = "CamelRabbitmqImmediate";
-    public static final String RABBITMQ_DEAD_LETTER_EXCHANGE = "x-dead-letter-exchange";
-    public static final String RABBITMQ_DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";
-    public static final String RABBITMQ_DIRECT_REPLY_EXCHANGE = "";
-    public static final String RABBITMQ_DIRECT_REPLY_ROUTING_KEY = "amq.rabbitmq.reply-to";
-    public static final String RABBITMQ_QUEUE_LENGTH_LIMIT_KEY = "x-max-length";
-    public static final String RABBITMQ_QUEUE_MAX_PRIORITY_KEY = "x-max-priority";
-    public static final String RABBITMQ_QUEUE_MESSAGE_TTL_KEY = "x-message-ttl";
-    public static final String RABBITMQ_QUEUE_TTL_KEY = "x-expires";
-    public static final String RABBITMQ_QUEUE_SINGLE_ACTIVE_CONSUMER_KEY = "x-single-active-consumer";
 
-    public static final Set<String> BASIC_AMQP_PROPERTIES = Stream
-            .of(CONTENT_TYPE, PRIORITY, MESSAGE_ID, CLUSTERID, REPLY_TO, CORRELATIONID, DELIVERY_MODE, USERID, TYPE,
-                    CONTENT_ENCODING, EXPIRATION, APP_ID, TIMESTAMP)
-            .collect(Collectors.toSet());
+    public static final String DEAD_LETTER_EXCHANGE = "x-dead-letter-exchange";
+    public static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";
+    public static final String MAX_LENGTH = "x-max-length";
+    public static final String MAX_PRIORITY = "x-max-priority";
+    public static final String MESSAGE_TTL = "x-message-ttl";
+    public static final String EXPIRES = "x-expires";
+    public static final String SINGLE_ACTIVE_CONSUMER = "x-single-active-consumer";
 
     private RabbitMQConstants() {
         // Constants class
diff --git a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQEndpoint.java b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQEndpoint.java
index f573e77..dbca4cb 100644
--- a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQEndpoint.java
+++ b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQEndpoint.java
@@ -55,6 +55,7 @@ import org.springframework.amqp.support.converter.MessageConverter;
 public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
 
     public static final String ARG_PREFIX = "arg.";
+    public static final String CONSUMER_ARG_PREFIX = "consumer.";
     public static final String EXCHANGE_ARG_PREFIX = "exchange.";
     public static final String QUEUE_ARG_PREFIX = "queue.";
     public static final String BINDING_ARG_PREFIX = "binding.";
@@ -108,7 +109,7 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
     private MessagePropertiesConverter messagePropertiesConverter;
     @UriParam(label = "advanced", prefix = ARG_PREFIX, multiValue = true,
               description = "Specify arguments for configuring the different RabbitMQ concepts, a different prefix is required for each element:"
-                            + " arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue. arg.dlq.binding."
+                            + " arg.consumer. arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue. arg.dlq.binding."
                             + " For example to declare a queue with message ttl argument: args=arg.queue.x-message-ttl=60000")
     private Map<String, Object> args;
     @UriParam(label = "consumer",
@@ -345,28 +346,46 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
         return exchange;
     }
 
+    public Map<String, Object> getConsumerArgs() {
+        Map<String, Object> answer = PropertiesHelper.extractProperties(args, CONSUMER_ARG_PREFIX, false);
+        prepareArgs(answer);
+        return answer;
+    }
+
     public Map<String, Object> getExchangeArgs() {
-        return PropertiesHelper.extractProperties(args, EXCHANGE_ARG_PREFIX, false);
+        Map<String, Object> answer = PropertiesHelper.extractProperties(args, EXCHANGE_ARG_PREFIX, false);
+        prepareArgs(answer);
+        return answer;
     }
 
     public Map<String, Object> getQueueArgs() {
-        return PropertiesHelper.extractProperties(args, QUEUE_ARG_PREFIX, false);
+        Map<String, Object> answer = PropertiesHelper.extractProperties(args, QUEUE_ARG_PREFIX, false);
+        prepareArgs(answer);
+        return answer;
     }
 
     public Map<String, Object> getBindingArgs() {
-        return PropertiesHelper.extractProperties(args, BINDING_ARG_PREFIX, false);
+        Map<String, Object> answer = PropertiesHelper.extractProperties(args, BINDING_ARG_PREFIX, false);
+        prepareArgs(answer);
+        return answer;
     }
 
     public Map<String, Object> getDlqExchangeArgs() {
-        return PropertiesHelper.extractProperties(args, DLQ_EXCHANGE_ARG_PREFIX, false);
+        Map<String, Object> answer = PropertiesHelper.extractProperties(args, DLQ_EXCHANGE_ARG_PREFIX, false);
+        prepareArgs(answer);
+        return answer;
     }
 
     public Map<String, Object> getDlqQueueArgs() {
-        return PropertiesHelper.extractProperties(args, DLQ_QUEUE_ARG_PREFIX, false);
+        Map<String, Object> answer = PropertiesHelper.extractProperties(args, DLQ_QUEUE_ARG_PREFIX, false);
+        prepareArgs(answer);
+        return answer;
     }
 
     public Map<String, Object> getDlqBindingArgs() {
-        return PropertiesHelper.extractProperties(args, DLQ_BINDING_PREFIX, false);
+        Map<String, Object> answer = PropertiesHelper.extractProperties(args, DLQ_BINDING_PREFIX, false);
+        prepareArgs(answer);
+        return answer;
     }
 
     /**
@@ -424,7 +443,6 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
                 if (deadLetterQueue != null) {
                     QueueBuilder qb = QueueBuilder.durable(deadLetterQueue);
                     Map<String, Object> args = getDlqQueueArgs();
-                    formatSpecialQueueArguments(args);
                     qb.withArguments(args);
                     final Queue rabbitQueue = qb.build();
                     admin.declareQueue(rabbitQueue);
@@ -464,8 +482,7 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
             if (queues != null) {
                 for (String queue : queues.split(",")) {
                     args = getQueueArgs();
-                    populateQueueArgumentsFromDeadLetterExchange(args);
-                    formatSpecialQueueArguments(args);
+                    prepareDeadLetterQueueArgs(args);
                     durable = parseArgsBoolean(args, "durable", "false");
                     autoDelete = parseArgsBoolean(args, "autoDelete", "false");
                     boolean exclusive = parseArgsBoolean(args, "exclusive", "false");
@@ -500,41 +517,41 @@ public class RabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint {
         }
     }
 
-    private void populateQueueArgumentsFromDeadLetterExchange(Map<String, Object> queueArgs) {
+    private void prepareDeadLetterQueueArgs(Map<String, Object> args) {
         if (deadLetterExchange != null) {
-            queueArgs.put(RabbitMQConstants.RABBITMQ_DEAD_LETTER_EXCHANGE, deadLetterExchange);
+            args.put(RabbitMQConstants.DEAD_LETTER_EXCHANGE, deadLetterExchange);
 
             if (deadLetterRoutingKey != null) {
-                queueArgs.put(RabbitMQConstants.RABBITMQ_DEAD_LETTER_ROUTING_KEY, deadLetterRoutingKey);
+                args.put(RabbitMQConstants.DEAD_LETTER_ROUTING_KEY, deadLetterRoutingKey);
             }
         }
     }
 
-    private void formatSpecialQueueArguments(Map<String, Object> queueArgs) {
+    private void prepareArgs(Map<String, Object> args) {
         // some arguments must be in numeric values so we need to fix this
-        Object queueLengthLimit = queueArgs.get(RabbitMQConstants.RABBITMQ_QUEUE_LENGTH_LIMIT_KEY);
+        Object queueLengthLimit = args.get(RabbitMQConstants.MAX_LENGTH);
         if (queueLengthLimit instanceof String) {
-            queueArgs.put(RabbitMQConstants.RABBITMQ_QUEUE_LENGTH_LIMIT_KEY, Long.parseLong((String) queueLengthLimit));
+            args.put(RabbitMQConstants.MAX_LENGTH, Long.parseLong((String) queueLengthLimit));
         }
 
-        Object queueMaxPriority = queueArgs.get(RabbitMQConstants.RABBITMQ_QUEUE_MAX_PRIORITY_KEY);
+        Object queueMaxPriority = args.get(RabbitMQConstants.MAX_PRIORITY);
         if (queueMaxPriority instanceof String) {
-            queueArgs.put(RabbitMQConstants.RABBITMQ_QUEUE_MAX_PRIORITY_KEY, Integer.parseInt((String) queueMaxPriority));
+            args.put(RabbitMQConstants.MAX_PRIORITY, Integer.parseInt((String) queueMaxPriority));
         }
 
-        Object queueMessageTtl = queueArgs.get(RabbitMQConstants.RABBITMQ_QUEUE_MESSAGE_TTL_KEY);
+        Object queueMessageTtl = args.get(RabbitMQConstants.MESSAGE_TTL);
         if (queueMessageTtl instanceof String) {
-            queueArgs.put(RabbitMQConstants.RABBITMQ_QUEUE_MESSAGE_TTL_KEY, Long.parseLong((String) queueMessageTtl));
+            args.put(RabbitMQConstants.MESSAGE_TTL, Long.parseLong((String) queueMessageTtl));
         }
 
-        Object queueExpiration = queueArgs.get(RabbitMQConstants.RABBITMQ_QUEUE_TTL_KEY);
+        Object queueExpiration = args.get(RabbitMQConstants.EXPIRES);
         if (queueExpiration instanceof String) {
-            queueArgs.put(RabbitMQConstants.RABBITMQ_QUEUE_TTL_KEY, Long.parseLong((String) queueExpiration));
+            args.put(RabbitMQConstants.EXPIRES, Long.parseLong((String) queueExpiration));
         }
 
-        Object singleConsumer = queueArgs.get(RabbitMQConstants.RABBITMQ_QUEUE_SINGLE_ACTIVE_CONSUMER_KEY);
+        Object singleConsumer = args.get(RabbitMQConstants.SINGLE_ACTIVE_CONSUMER);
         if (singleConsumer instanceof String) {
-            queueArgs.put(RabbitMQConstants.RABBITMQ_QUEUE_SINGLE_ACTIVE_CONSUMER_KEY,
+            args.put(RabbitMQConstants.SINGLE_ACTIVE_CONSUMER,
                     Boolean.parseBoolean((String) singleConsumer));
         }
     }
diff --git a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQMessageConverter.java b/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQMessageConverter.java
deleted file mode 100644
index dace98f..0000000
--- a/components/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/RabbitMQMessageConverter.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.springrabbit;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import com.rabbitmq.client.AMQP;
-import com.rabbitmq.client.Envelope;
-import com.rabbitmq.client.LongString;
-import org.apache.camel.Exchange;
-import org.apache.camel.Message;
-import org.apache.camel.spi.HeaderFilterStrategy;
-import org.apache.camel.support.DefaultMessage;
-import org.apache.camel.util.ObjectHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RabbitMQMessageConverter {
-    protected static final Logger LOG = LoggerFactory.getLogger(RabbitMQMessageConverter.class);
-
-    private boolean allowNullHeaders;
-    private boolean allowCustomHeaders;
-    private Map<String, Object> additionalHeaders;
-    private Map<String, Object> additionalProperties;
-    private final HeaderFilterStrategy headerFilterStrategy = new RabbitMQHeaderFilterStrategy();
-
-    /**
-     * Will take an {@link Exchange} and add header values back to the {@link Exchange#getIn()}
-     */
-    public void mergeAmqpProperties(Exchange exchange, AMQP.BasicProperties properties) {
-
-        if (properties.getType() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.TYPE, properties.getType());
-        }
-        if (properties.getAppId() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.APP_ID, properties.getAppId());
-        }
-        if (properties.getClusterId() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.CLUSTERID, properties.getClusterId());
-        }
-        if (properties.getContentEncoding() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.CONTENT_ENCODING, properties.getContentEncoding());
-        }
-        if (properties.getContentType() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.CONTENT_TYPE, properties.getContentType());
-        }
-        if (properties.getCorrelationId() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.CORRELATIONID, properties.getCorrelationId());
-        }
-        if (properties.getExpiration() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.EXPIRATION, properties.getExpiration());
-        }
-        if (properties.getMessageId() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.MESSAGE_ID, properties.getMessageId());
-        }
-        if (properties.getPriority() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.PRIORITY, properties.getPriority());
-        }
-        if (properties.getReplyTo() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.REPLY_TO, properties.getReplyTo());
-        }
-        if (properties.getTimestamp() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.TIMESTAMP, properties.getTimestamp());
-        }
-        if (properties.getUserId() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.USERID, properties.getUserId());
-        }
-        if (properties.getDeliveryMode() != null) {
-            exchange.getIn().setHeader(RabbitMQConstants.DELIVERY_MODE, properties.getDeliveryMode());
-        }
-    }
-
-    public AMQP.BasicProperties.Builder buildProperties(Exchange exchange) {
-        Message msg = exchange.getMessage();
-
-        AMQP.BasicProperties.Builder properties = buildBasicAmqpProperties(exchange.getProperties(), msg);
-
-        final Map<String, Object> headers = properties.build().getHeaders();
-        // Add additional headers (if any)
-        if (additionalHeaders != null) {
-            headers.putAll(additionalHeaders);
-        }
-        Map<String, Object> filteredHeaders = new HashMap<>();
-
-        for (Map.Entry<String, Object> header : headers.entrySet()) {
-            // filter header values.
-            Object value = getValidRabbitMQHeaderValue(header.getKey(), header.getValue());
-
-            // additionally filter out the OVERRIDE header so it does not
-            // propagate
-            if ((value != null || isAllowNullHeaders()) && !header.getKey()
-                    .equals(RabbitMQConstants.EXCHANGE_OVERRIDE_NAME)) {
-                boolean filteredHeader;
-                if (!allowCustomHeaders) {
-                    filteredHeader = headerFilterStrategy
-                            .applyFilterToCamelHeaders(header.getKey(), header.getValue(), exchange);
-                    if (filteredHeader) {
-                        filteredHeaders.put(header.getKey(), header.getValue());
-                    }
-                } else {
-                    filteredHeaders.put(header.getKey(), header.getValue());
-                }
-            } else if (LOG.isDebugEnabled()) {
-                if (header.getValue() == null) {
-                    LOG.debug("Ignoring header: {} with null value", header.getKey());
-                } else if (header.getKey().equals(RabbitMQConstants.EXCHANGE_OVERRIDE_NAME)) {
-                    LOG.debug("Preventing header propagation: {} with value {}:", header.getKey(),
-                            header.getValue());
-                } else {
-                    LOG.debug("Ignoring header: {} of class: {} with value: {}", header.getKey(),
-                            ObjectHelper.classCanonicalName(header.getValue()), header.getValue());
-                }
-            }
-        }
-
-        properties.headers(filteredHeaders);
-
-        return properties;
-    }
-
-    private AMQP.BasicProperties.Builder buildBasicAmqpProperties(
-            Map<String, Object> exchangeProperties, Message msg) {
-        AMQP.BasicProperties.Builder properties = new AMQP.BasicProperties.Builder();
-
-        final Map<String, Object> headers = new HashMap<>(msg.getHeaders()); // We don't want to mutate the message headers
-        final Object contentType = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.CONTENT_TYPE);
-        if (contentType != null) {
-            properties.contentType(contentType.toString());
-        }
-
-        final Object priority = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.PRIORITY);
-        if (priority != null) {
-            properties.priority(Integer.parseInt(priority.toString()));
-        }
-
-        final Object messageId = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.MESSAGE_ID);
-        if (messageId != null) {
-            properties.messageId(messageId.toString());
-        }
-
-        final Object clusterId = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.CLUSTERID);
-        if (clusterId != null) {
-            properties.clusterId(clusterId.toString());
-        }
-
-        final Object replyTo = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.REPLY_TO);
-        if (replyTo != null) {
-            properties.replyTo(replyTo.toString());
-        }
-
-        final Object correlationId = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.CORRELATIONID);
-        if (correlationId != null) {
-            properties.correlationId(correlationId.toString());
-        }
-
-        final Object deliveryMode = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.DELIVERY_MODE);
-        if (deliveryMode != null) {
-            properties.deliveryMode(Integer.parseInt(deliveryMode.toString()));
-        }
-
-        final Object userId = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.USERID);
-        if (userId != null) {
-            properties.userId(userId.toString());
-        }
-
-        final Object type = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.TYPE);
-        if (type != null) {
-            properties.type(type.toString());
-        }
-
-        final Object contentEncoding = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.CONTENT_ENCODING);
-        if (contentEncoding != null) {
-            properties.contentEncoding(contentEncoding.toString());
-        }
-
-        final Object expiration = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.EXPIRATION);
-        if (expiration != null) {
-            properties.expiration(expiration.toString());
-        }
-
-        final Object appId = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.APP_ID);
-        if (appId != null) {
-            properties.appId(appId.toString());
-        }
-
-        final Object timestamp = getBasicAmqpProperty(exchangeProperties, headers, RabbitMQConstants.TIMESTAMP);
-        if (timestamp != null) {
-            properties.timestamp(convertTimestamp(timestamp));
-        }
-
-        String ignoredProperties = exchangeProperties.keySet().stream()
-                .filter(key -> !RabbitMQConstants.BASIC_AMQP_PROPERTIES.contains(key))
-                .collect(Collectors.joining(", "));
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Added AMQP basic properties: {}", properties.build().toString());
-            LOG.debug("Ignoring non-AMQP basic properties: {}", ignoredProperties);
-        }
-
-        properties.headers(headers);
-
-        return properties;
-    }
-
-    private Object getBasicAmqpProperty(
-            Map<String, Object> exchangeProperties, Map<String, Object> headers,
-            String propertyKey) {
-        boolean hasAdditionalProps = additionalProperties != null && !additionalProperties
-                .isEmpty();
-        Object object = headers.remove(propertyKey);
-
-        if (exchangeProperties.containsKey(propertyKey)) {
-            object = exchangeProperties.get(propertyKey);
-        }
-        if (object == null && hasAdditionalProps) {
-            object = additionalProperties.get(propertyKey);
-        }
-        return object;
-    }
-
-    private Date convertTimestamp(Object timestamp) {
-        if (timestamp instanceof Date) {
-            return (Date) timestamp;
-        }
-        return new Date(Long.parseLong(timestamp.toString()));
-    }
-
-    /**
-     * Strategy to test if the given header is valid. Without this, the com.rabbitmq.client.impl.Frame.java class will
-     * throw an IllegalArgumentException (invalid value in table) and close the connection.
-     *
-     * @param  headerValue the header value
-     * @return             the value to use, <tt>null</tt> to ignore this header
-     * @see                com.rabbitmq.client.impl.Frame#fieldValueSize(Object)
-     */
-    private Object getValidRabbitMQHeaderValue(String headerKey, Object headerValue) {
-        // accept all x- headers
-        if (headerKey.startsWith("x-") || headerKey.startsWith("X-")) {
-            return headerKey;
-        }
-
-        if (headerValue instanceof String) {
-            return headerValue;
-        } else if (headerValue instanceof Number) {
-            return headerValue;
-        } else if (headerValue instanceof Boolean) {
-            return headerValue;
-        } else if (headerValue instanceof Date) {
-            return headerValue;
-        } else if (headerValue instanceof byte[]) {
-            return headerValue;
-        } else if (headerValue instanceof LongString) {
-            return headerValue;
-        } else if (headerValue instanceof Map) {
-            return headerValue;
-        } else if (headerValue instanceof List) {
-            return headerValue;
-        }
-
-        return null;
-    }
-
-    public void populateRabbitExchange(
-            Exchange camelExchange, Envelope envelope, AMQP.BasicProperties properties, byte[] body, final boolean out,
-            final boolean allowMessageBodySerialization) {
-        Message message = resolveMessageFrom(camelExchange, out);
-        populateMessageHeaders(message, envelope, properties);
-        populateMessageBody(message, camelExchange, properties, body, allowMessageBodySerialization);
-    }
-
-    private Message resolveMessageFrom(final Exchange camelExchange, final boolean out) {
-        Message message;
-        if (out) {
-            // use OUT message
-            message = camelExchange.getOut();
-        } else {
-            if (camelExchange.getIn() != null) {
-                // Use the existing message so we keep the headers
-                message = camelExchange.getIn();
-            } else {
-                message = new DefaultMessage(camelExchange.getContext());
-                camelExchange.setIn(message);
-            }
-        }
-        return message;
-    }
-
-    private void populateMessageHeaders(final Message message, final Envelope envelope, final AMQP.BasicProperties properties) {
-        populateRoutingInfoHeaders(message, envelope);
-        populateMessageHeadersFromRabbitMQHeaders(message, properties);
-    }
-
-    private void populateRoutingInfoHeaders(final Message message, final Envelope envelope) {
-        if (envelope != null) {
-            message.setHeader(RabbitMQConstants.ROUTING_KEY, envelope.getRoutingKey());
-            message.setHeader(RabbitMQConstants.EXCHANGE_NAME, envelope.getExchange());
-            message.setHeader(RabbitMQConstants.DELIVERY_TAG, envelope.getDeliveryTag());
-            message.setHeader(RabbitMQConstants.REDELIVERY_TAG, envelope.isRedeliver());
-        }
-    }
-
-    private void populateMessageHeadersFromRabbitMQHeaders(final Message message, final AMQP.BasicProperties properties) {
-        Map<String, Object> headers = properties.getHeaders();
-        if (headers != null) {
-            for (Map.Entry<String, Object> entry : headers.entrySet()) {
-                // Convert LongStrings to String.
-                if (entry.getValue() instanceof LongString) {
-                    message.setHeader(entry.getKey(), entry.getValue().toString());
-                } else {
-                    message.setHeader(entry.getKey(), entry.getValue());
-                }
-            }
-        }
-    }
-
-    private void populateMessageBody(
-            final Message message, final Exchange camelExchange, final AMQP.BasicProperties properties, final byte[] body,
-            final boolean allowMessageBodySerialization) {
-        if (allowMessageBodySerialization && hasSerializeHeader(properties)) {
-            deserializeBody(camelExchange, message, body);
-        } else {
-            // Set the body as a byte[] and let the type converter deal with it
-            message.setBody(body);
-        }
-    }
-
-    private void deserializeBody(final Exchange camelExchange, final Message message, final byte[] body) {
-        Object messageBody = null;
-        try (InputStream b = new ByteArrayInputStream(body); ObjectInputStream o = new ObjectInputStream(b)) {
-            messageBody = o.readObject();
-        } catch (IOException | ClassNotFoundException e) {
-            LOG.warn("Could not deserialize the object");
-            camelExchange.setException(e);
-        }
-        if (messageBody instanceof Throwable) {
-            LOG.debug("Reply was an Exception. Setting the Exception on the Exchange");
-            camelExchange.setException((Throwable) messageBody);
-        } else {
-            message.setBody(messageBody);
-        }
-    }
-
-    private boolean hasSerializeHeader(AMQP.BasicProperties properties) {
-        return hasHeaders(properties) && Boolean.TRUE.equals(isSerializeHeaderEnabled(properties));
-    }
-
-    private boolean hasHeaders(final AMQP.BasicProperties properties) {
-        return properties != null && properties.getHeaders() != null;
-    }
-
-    private Object isSerializeHeaderEnabled(final AMQP.BasicProperties properties) {
-        // TODO:
-        return false;
-        // return properties.getHeaders().get(RabbitMQEndpoint.SERIALIZE_HEADER);
-    }
-
-    public boolean isAllowNullHeaders() {
-        return allowNullHeaders;
-    }
-
-    public void setAllowNullHeaders(boolean allowNullHeaders) {
-        this.allowNullHeaders = allowNullHeaders;
-    }
-
-    public boolean isAllowCustomHeaders() {
-        return allowCustomHeaders;
-    }
-
-    public void setAllowCustomHeaders(boolean allowCustomHeaders) {
-        this.allowCustomHeaders = allowCustomHeaders;
-    }
-
-    public void setAdditionalHeaders(Map<String, Object> additionalHeaders) {
-        this.additionalHeaders = additionalHeaders;
-    }
-
-    public Map<String, Object> getAdditionalHeaders() {
-        return additionalHeaders;
-    }
-
-    public void setAdditionalProperties(
-            Map<String, Object> additionalProperties) {
-        this.additionalProperties = additionalProperties;
-    }
-
-    public Map<String, Object> getAdditionalProperties() {
-        return additionalProperties;
-    }
-}
diff --git a/components/camel-spring-rabbitmq/src/test/resources/log4j2.properties b/components/camel-spring-rabbitmq/src/test/resources/log4j2.properties
index a9d4d76..65dda4d 100644
--- a/components/camel-spring-rabbitmq/src/test/resources/log4j2.properties
+++ b/components/camel-spring-rabbitmq/src/test/resources/log4j2.properties
@@ -26,7 +26,7 @@ appender.out.layout.type = PatternLayout
 appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
 rootLogger.level = INFO
 rootLogger.appenderRef.file.ref = file
-rootLogger.appenderRef.out.ref = out
+#rootLogger.appenderRef.out.ref = out
 
-logger.rabbit.name = org.springframework.amqp.rabbit
-logger.rabbit.level = DEBUG
\ No newline at end of file
+#logger.rabbit.name = org.springframework.amqp.rabbit
+#logger.rabbit.level = DEBUG
\ No newline at end of file
diff --git a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SpringRabbitmqComponentBuilderFactory.java b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SpringRabbitmqComponentBuilderFactory.java
index 7ab6d93..65ae914 100644
--- a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SpringRabbitmqComponentBuilderFactory.java
+++ b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SpringRabbitmqComponentBuilderFactory.java
@@ -106,6 +106,22 @@ public interface SpringRabbitmqComponentBuilderFactory {
             return this;
         }
         /**
+         * Specifies whether the consumer should auto declare binding between
+         * exchange, queue and routing key when starting.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: true
+         * Group: consumer
+         * 
+         * @param autoDeclare the value to set
+         * @return the dsl builder
+         */
+        default SpringRabbitmqComponentBuilder autoDeclare(boolean autoDeclare) {
+            doSetProperty("autoDeclare", autoDeclare);
+            return this;
+        }
+        /**
          * Specifies whether the consumer container should auto-startup.
          * 
          * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
@@ -390,6 +406,7 @@ public interface SpringRabbitmqComponentBuilderFactory {
             case "amqpAdmin": ((RabbitMQComponent) component).setAmqpAdmin((org.springframework.amqp.core.AmqpAdmin) value); return true;
             case "connectionFactory": ((RabbitMQComponent) component).setConnectionFactory((org.springframework.amqp.rabbit.connection.ConnectionFactory) value); return true;
             case "testConnectionOnStartup": ((RabbitMQComponent) component).setTestConnectionOnStartup((boolean) value); return true;
+            case "autoDeclare": ((RabbitMQComponent) component).setAutoDeclare((boolean) value); return true;
             case "autoStartup": ((RabbitMQComponent) component).setAutoStartup((boolean) value); return true;
             case "bridgeErrorHandler": ((RabbitMQComponent) component).setBridgeErrorHandler((boolean) value); return true;
             case "deadLetterExchange": ((RabbitMQComponent) component).setDeadLetterExchange((java.lang.String) value); return true;
diff --git a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/RabbitMQEndpointBuilderFactory.java b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/RabbitMQEndpointBuilderFactory.java
index f5361a3..5891358 100644
--- a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/RabbitMQEndpointBuilderFactory.java
+++ b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/RabbitMQEndpointBuilderFactory.java
@@ -629,10 +629,10 @@ public interface RabbitMQEndpointBuilderFactory {
         }
         /**
          * Specify arguments for configuring the different RabbitMQ concepts, a
-         * different prefix is required for each element: arg.exchange.
-         * arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue.
-         * arg.dlq.binding. For example to declare a queue with message ttl
-         * argument: args=arg.queue.x-message-ttl=60000.
+         * different prefix is required for each element: arg.consumer.
+         * arg.exchange. arg.queue. arg.binding. arg.dlq.exchange.
+         * arg.dlq.queue. arg.dlq.binding. For example to declare a queue with
+         * message ttl argument: args=arg.queue.x-message-ttl=60000.
          * 
          * The option is a: &lt;code&gt;java.util.Map&amp;lt;java.lang.String,
          * java.lang.Object&amp;gt;&lt;/code&gt; type.
@@ -654,10 +654,10 @@ public interface RabbitMQEndpointBuilderFactory {
         }
         /**
          * Specify arguments for configuring the different RabbitMQ concepts, a
-         * different prefix is required for each element: arg.exchange.
-         * arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue.
-         * arg.dlq.binding. For example to declare a queue with message ttl
-         * argument: args=arg.queue.x-message-ttl=60000.
+         * different prefix is required for each element: arg.consumer.
+         * arg.exchange. arg.queue. arg.binding. arg.dlq.exchange.
+         * arg.dlq.queue. arg.dlq.binding. For example to declare a queue with
+         * message ttl argument: args=arg.queue.x-message-ttl=60000.
          * 
          * The option is a: &lt;code&gt;java.util.Map&amp;lt;java.lang.String,
          * java.lang.Object&amp;gt;&lt;/code&gt; type.
@@ -1021,10 +1021,10 @@ public interface RabbitMQEndpointBuilderFactory {
         }
         /**
          * Specify arguments for configuring the different RabbitMQ concepts, a
-         * different prefix is required for each element: arg.exchange.
-         * arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue.
-         * arg.dlq.binding. For example to declare a queue with message ttl
-         * argument: args=arg.queue.x-message-ttl=60000.
+         * different prefix is required for each element: arg.consumer.
+         * arg.exchange. arg.queue. arg.binding. arg.dlq.exchange.
+         * arg.dlq.queue. arg.dlq.binding. For example to declare a queue with
+         * message ttl argument: args=arg.queue.x-message-ttl=60000.
          * 
          * The option is a: &lt;code&gt;java.util.Map&amp;lt;java.lang.String,
          * java.lang.Object&amp;gt;&lt;/code&gt; type.
@@ -1046,10 +1046,10 @@ public interface RabbitMQEndpointBuilderFactory {
         }
         /**
          * Specify arguments for configuring the different RabbitMQ concepts, a
-         * different prefix is required for each element: arg.exchange.
-         * arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue.
-         * arg.dlq.binding. For example to declare a queue with message ttl
-         * argument: args=arg.queue.x-message-ttl=60000.
+         * different prefix is required for each element: arg.consumer.
+         * arg.exchange. arg.queue. arg.binding. arg.dlq.exchange.
+         * arg.dlq.queue. arg.dlq.binding. For example to declare a queue with
+         * message ttl argument: args=arg.queue.x-message-ttl=60000.
          * 
          * The option is a: &lt;code&gt;java.util.Map&amp;lt;java.lang.String,
          * java.lang.Object&amp;gt;&lt;/code&gt; type.
@@ -1329,10 +1329,10 @@ public interface RabbitMQEndpointBuilderFactory {
         }
         /**
          * Specify arguments for configuring the different RabbitMQ concepts, a
-         * different prefix is required for each element: arg.exchange.
-         * arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue.
-         * arg.dlq.binding. For example to declare a queue with message ttl
-         * argument: args=arg.queue.x-message-ttl=60000.
+         * different prefix is required for each element: arg.consumer.
+         * arg.exchange. arg.queue. arg.binding. arg.dlq.exchange.
+         * arg.dlq.queue. arg.dlq.binding. For example to declare a queue with
+         * message ttl argument: args=arg.queue.x-message-ttl=60000.
          * 
          * The option is a: &lt;code&gt;java.util.Map&amp;lt;java.lang.String,
          * java.lang.Object&amp;gt;&lt;/code&gt; type.
@@ -1352,10 +1352,10 @@ public interface RabbitMQEndpointBuilderFactory {
         }
         /**
          * Specify arguments for configuring the different RabbitMQ concepts, a
-         * different prefix is required for each element: arg.exchange.
-         * arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue.
-         * arg.dlq.binding. For example to declare a queue with message ttl
-         * argument: args=arg.queue.x-message-ttl=60000.
+         * different prefix is required for each element: arg.consumer.
+         * arg.exchange. arg.queue. arg.binding. arg.dlq.exchange.
+         * arg.dlq.queue. arg.dlq.binding. For example to declare a queue with
+         * message ttl argument: args=arg.queue.x-message-ttl=60000.
          * 
          * The option is a: &lt;code&gt;java.util.Map&amp;lt;java.lang.String,
          * java.lang.Object&amp;gt;&lt;/code&gt; type.
diff --git a/docs/components/modules/ROOT/pages/spring-rabbitmq-component.adoc b/docs/components/modules/ROOT/pages/spring-rabbitmq-component.adoc
index 614144a..e3217e0 100644
--- a/docs/components/modules/ROOT/pages/spring-rabbitmq-component.adoc
+++ b/docs/components/modules/ROOT/pages/spring-rabbitmq-component.adoc
@@ -45,7 +45,7 @@ determines the exchange the queue will be bound to.
 == Options
 
 // component options: START
-The Spring RabbitMQ component supports 18 options, which are listed below.
+The Spring RabbitMQ component supports 19 options, which are listed below.
 
 
 
@@ -55,6 +55,7 @@ The Spring RabbitMQ component supports 18 options, which are listed below.
 | *amqpAdmin* (common) | *Autowired* Optional AMQP Admin service to use for auto declaring elements (queues, exchanges, bindings) |  | AmqpAdmin
 | *connectionFactory* (common) | *Autowired* The connection factory to be use. A connection factory must be configured either on the component or endpoint. |  | ConnectionFactory
 | *testConnectionOnStartup* (common) | Specifies whether to test the connection on startup. This ensures that when Camel starts that all the JMS consumers have a valid connection to the JMS broker. If a connection cannot be granted then Camel throws an exception on startup. This ensures that Camel is not started with failed connections. The JMS producers is tested as well. | false | boolean
+| *autoDeclare* (consumer) | Specifies whether the consumer should auto declare binding between exchange, queue and routing key when starting. | true | boolean
 | *autoStartup* (consumer) | Specifies whether the consumer container should auto-startup. | true | boolean
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
 | *deadLetterExchange* (consumer) | The name of the dead letter exchange |  | String
@@ -120,7 +121,7 @@ with the following path and query parameters:
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
 | *replyTimeout* (producer) | Specify the timeout in milliseconds to be used when waiting for a reply message when doing request/reply messaging. The default value is 5 seconds. A negative value indicates an indefinite timeout. | 5000 | long
-| *args* (advanced) | Specify arguments for configuring the different RabbitMQ concepts, a different prefix is required for each element: arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue. arg.dlq.binding. For example to declare a queue with message ttl argument: args=arg.queue.x-message-ttl=60000 |  | Map
+| *args* (advanced) | Specify arguments for configuring the different RabbitMQ concepts, a different prefix is required for each element: arg.consumer. arg.exchange. arg.queue. arg.binding. arg.dlq.exchange. arg.dlq.queue. arg.dlq.binding. For example to declare a queue with message ttl argument: args=arg.queue.x-message-ttl=60000 |  | Map
 | *messageConverter* (advanced) | To use a custom MessageConverter so you can be in control how to map to/from a org.springframework.amqp.core.Message. |  | MessageConverter
 | *messagePropertiesConverter* (advanced) | To use a custom MessagePropertiesConverter so you can be in control how to map to/from a org.springframework.amqp.core.MessageProperties. |  | MessagePropertiesConverter
 | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
@@ -131,13 +132,12 @@ with the following path and query parameters:
 
 To connect to RabbitMQ you need to setup a `ConnectionFactory` (same as with JMS) with the login details such as:
 
+TIP: It is recommended to use `CachingConnectionFactory` from spring-rabbit as it comes with connection pooling out of the box.
+
 [source,xml]
 ----
-<bean id="rabbitConnectionFactory" class="com.rabbitmq.client.ConnectionFactory">
-  <property name="host" value="localhost"/>
-  <property name="port" value="5672"/>
-  <property name="username" value="camel"/>
-  <property name="password" value="bugsbunny"/>
+<bean id="rabbitConnectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
+  <property name="uri" value="amqp://lolcalhost:5672"/>
 </bean>
 ----
 
@@ -147,11 +147,107 @@ The `ConnectionFactory` is auto-detected by default, so you can just do
 ----
 <camelContext>
   <route>
-    <from uri="direct:rabbitMQEx2"/>
-    <to uri="spring-rabbitmq:ex2"/>
+    <from uri="direct:cheese"/>
+    <to uri="spring-rabbitmq:foo?routingKey=cheese"/>
   </route>
 </camelContext>
 ----
 
+== Request / Reply
+
+Request and reply messaging is supported using https://www.rabbitmq.com/direct-reply-to.html[RabbitMQ direct reply-to].
+
+The example below will do request/reply, where the message is sent via the cheese exchange name and routing key _foo.bar_,
+which is being consumed by the 2nd Camel route, that prepends the message with `Hello `, and then sends back the message.
+
+So if we send `World` as message body to _direct:start_ then, we will se the message being logged
+
+- log:request => World
+- log:input => World
+- log:response => Hello World
+
+[source,java]
+----
+from("direct:start")
+    .to("log:request")
+    .to(ExchangePattern.InOut, "spring-rabbitmq:cheese?routingKey=foo.bar")
+    .to("log:response");
+
+from("spring-rabbitmq:cheese?queues=myqueue&routingKey=foo.bar")
+    .to("log:input")
+    .transform(body().prepend("Hello "));
+----
+
+The Spring RabbitMQ will automatic nessasary declare the elements and setup the binding between the exchange, queue and routing keys.
+This can be turned off by setting `autoDeclare=false`.
+
+== Reuse endpoint and send to different destinations computed at runtime
+
+If you need to send messages to a lot of different RabbitMQ exchanges, it
+makes sense to reuse a endpoint and specify the real destination in
+a message header. This allows Camel to reuse the same endpoint, but send
+to different exchanges. This greatly reduces the number of endpoints
+created and economizes on memory and thread resources.
+
+TIP: Using xref:{eip-vc}:eips:toD-eip.adoc[toD] is easier than specifying the dynamic destination with headers
+
+You can specify using the following headers:
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=====================================================================
+|Header |Type |Description
+|`CamelRabbitmqExchangeOverrideName` |`String` |The exchange name.
+|`CamelRabbitmqRoutingOverrideKey` |`String` |The routing key.
+|=====================================================================
+
+For example, the following route shows how you can compute a destination
+at run time and use it to override the exchange appearing in the endpoint
+URL:
+
+[source,java]
+----
+from("file://inbox")
+  .to("bean:computeDestination")
+  .to("spring-rabbitmq:dummy");
+----
+
+The exchange name, `dummy`, is just a placeholder. It must be provided as
+part of the RabbitMQ endpoint URL, but it will be ignored in this example.
+
+In the `computeDestination` bean, specify the real destination by
+setting the `CamelRabbitmqExchangeOverrideName` header as follows:
+
+[source,java]
+----
+public void setExchangeHeader(Exchange exchange) {
+   String region = ....
+   exchange.getIn().setHeader("CamelRabbitmqExchangeOverrideName", "order-" + region);
+}
+----
+
+Then Camel will read this header and use it as the exchange name instead
+of the one configured on the endpoint. So, in this example Camel sends
+the message to `spring-rabbitmq:order-emea`, assuming the `region` value was `emea`.
+
+Keep in mind that the producer removes both `CamelRabbitmqExchangeOverrideName` and `CamelRabbitmqRoutingOverrideKey`
+headers from the exchange and do not propagate them to the created Rabbitmq
+message in order to avoid the accidental loops
+in the routes (in scenarios when the message will be forwarded to the
+another RabbitMQ endpoint).
+
+== Using toD
+
+If you need to send messages to a lot of different exchanges, it
+makes sense to reuse a endpoint and specify the dynamic destinations
+with simple language using xref:{eip-vc}:eips:toD-eip.adoc[toD].
+
+For example suppose you need to send messages to exchanges with order types,
+then using toD could for example be done as follows:
+
+[source,java]
+----
+from("direct:order")
+  .toD("spring-rabbit:order-${header.orderType}");
+----
 
 include::camel-spring-boot::page$rabbitmq-starter.adoc[]