You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by cd...@apache.org on 2023/07/04 11:56:48 UTC

[camel] 01/03: CAMEL-18698 Add support for multiple input/output data types on components

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

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

commit 55191eca46a46ced9f73eb82751a5eca7d599f14
Author: Christoph Deppisch <cd...@redhat.com>
AuthorDate: Wed Jun 28 08:54:44 2023 +0200

    CAMEL-18698 Add support for multiple input/output data types on components
    
    - Add data type to transform EIP resulting in a transformation from given type to target type using a matching transformer implementation
    - Enhance data type transformer resolving mechanism as follows:
    - Add lazy loading of transformer implementations via resource path factory finder
    - Add annotation based transformer loader (adds possibility to load transformer implementations with classpath scan)
    - Add possibility to configure preloading of default Camel transformer implementations
    - Add default Camel transformer implementations for String and byte[]
    - Add CloudEvents transformer implementation to transform any Camel Exchange into CloudEvent Http or Json binding
    - Add AWS S3 CloudEvents transformer implementation to transform getObject response into proper CloudEvent
---
 .../org/apache/camel/catalog/models/transform.json |   8 +-
 .../apache/camel/catalog/models/transformers.json  |   2 +-
 .../apache/camel/catalog/schemas/camel-spring.xsd  |  29 +++
 components/camel-aws/camel-aws2-s3/pom.xml         |   8 +
 .../AWS2S3CloudEventDataTypeTransformer.java       |  54 ++++++
 .../transformer/aws2-s3-application-cloudevents    |  18 ++
 .../AWS2S3CloudEventDataTypeTransformerTest.java   |  69 +++++++
 .../transform/AWS2S3TransformCloudEventsTest.java  |  82 +++++++++
 components/camel-cloudevents/pom.xml               |   7 +
 .../camel/component/cloudevents/CloudEvent.java    |  16 ++
 .../CloudEventHttpDataTypeTransformer.java         |  69 +++++++
 .../CloudEventJsonDataTypeTransformer.java         |  88 +++++++++
 .../transformer/application-cloudevents-json       |  18 ++
 .../transformer/http-application-cloudevents       |  18 ++
 .../CloudEventHttpDataTypeTransformerTest.java     | 110 ++++++++++++
 .../CloudEventJsonDataTypeTransformerTest.java     | 103 +++++++++++
 .../transformer/SpringTransformerRouteTest.xml     |  18 +-
 .../main/java/org/apache/camel/CamelContext.java   |  14 +-
 .../main/java/org/apache/camel/spi/DataType.java   |  57 ++++--
 .../org/apache/camel/spi/DataTypeTransformer.java  |  60 +++++++
 .../java/org/apache/camel/spi/Transformer.java     |  62 ++++++-
 .../org/apache/camel/spi/TransformerLoader.java}   |  20 ++-
 .../org/apache/camel/spi/TransformerResolver.java  |  54 ++++++
 .../camel/impl/engine/AbstractCamelContext.java    |   4 +-
 .../impl/engine/DefaultTransformerRegistry.java    | 121 +++++++++++--
 .../impl/engine/DefaultTransformerResolver.java    |  65 +++++++
 .../impl/engine/DefaultValidatorRegistry.java      |   2 +-
 .../apache/camel/impl/engine/TransformerKey.java   |  46 +++--
 .../org/apache/camel/impl/DefaultCamelContext.java |  12 +-
 .../org/apache/camel/model/transform.json          |   8 +-
 .../org/apache/camel/model/transformer/jaxb.index  |   1 +
 .../camel/model/transformer/transformers.json      |   2 +-
 .../apache/camel/builder/TransformerBuilder.java   |  55 +++++-
 .../apache/camel/model/ProcessorDefinition.java    |  28 +++
 .../apache/camel/model/TransformDefinition.java    |  50 ++++++
 .../transformer/LoadTransformerDefinition.java     |  64 +++++++
 .../model/transformer/TransformerDefinition.java   |  31 +++-
 .../model/transformer/TransformersDefinition.java  |   1 +
 .../org/apache/camel/processor/ContractAdvice.java |  45 +++--
 .../transformer/AnnotationTransformerLoader.java   | 198 +++++++++++++++++++++
 .../transformer/ByteArrayDataTypeTransformer.java} |  31 ++--
 .../transformer/DataFormatTransformer.java         |  16 +-
 .../processor/transformer/DataTypeProcessor.java   | 120 +++++++++++++
 .../transformer/DefaultTransformerLoader.java      |  48 +++++
 .../transformer/ProcessorTransformer.java          |   7 +-
 .../transformer/StringDataTypeTransformer.java     |  46 +++++
 .../transformer/TypeConverterTransformer.java      |  80 +++++++++
 .../datatype/transformer/application-octet-stream  |  18 ++
 .../apache/camel/datatype/transformer/plain-text   |  18 ++
 .../org/apache/camel/reifier/TransformReifier.java |  10 ++
 .../transformer/CustomTransformerReifier.java      |   5 +-
 .../transformer/DataFormatTransformerReifier.java  |   3 +-
 .../transformer/EndpointTransformerReifier.java    |   2 +-
 ...merReifier.java => LoadTransformerReifier.java} |  25 +--
 .../reifier/transformer/TransformerReifier.java    |   3 +
 .../core/xml/AbstractCamelContextFactoryBean.java  |  12 +-
 .../camel/builder/TransformerBuilderTest.java      |   2 +-
 .../engine/DefaultTransformerRegistryTest.java     |  47 +++++
 .../engine/DefaultTransformerResolverTest.java     |  75 ++++++++
 .../impl/engine/LowercaseDataTypeTransformer.java} |  19 +-
 .../impl/engine/UppercaseDataTypeTransformer.java} |  19 +-
 .../processor/TransformDataTypeProcessorTest.java  |  45 +++++
 .../ByteArrayDataTypeTransformerTest.java          | 101 +++++++++++
 .../transformer/DataTypeProcessorTest.java         |  79 ++++++++
 .../transformer/StringDataTypeTransformerTest.java |  89 +++++++++
 .../transformer/TransformerRouteTest.java          |  19 +-
 .../custom/CustomDataTypeTransformer.java}         |  19 +-
 .../org/apache/camel/datatype/transformer/foo-json |  18 ++
 .../apache/camel/datatype/transformer/lowercase    |  18 ++
 .../apache/camel/datatype/transformer/uppercase    |  18 ++
 .../api/management/mbean/CamelOpenMBeanTypes.java  |   6 +-
 .../management/mbean/ManagedTransformMBean.java    |   6 +
 .../DefaultManagementObjectStrategy.java           |   5 +-
 .../camel/management/mbean/ManagedTransformer.java |  16 +-
 .../mbean/ManagedTransformerRegistry.java          |  10 +-
 .../management/ManagedTransformerRegistryTest.java |  16 +-
 .../java/org/apache/camel/xml/in/ModelParser.java  |  22 ++-
 .../java/org/apache/camel/xml/out/ModelWriter.java |  14 ++
 .../org/apache/camel/yaml/out/ModelWriter.java     |  14 ++
 .../dsl/yaml/deserializers/ModelDeserializers.java | 110 +++++++++++-
 .../deserializers/ModelDeserializersResolver.java  |   1 +
 .../generated/resources/schema/camel-yaml-dsl.json |  47 +++++
 .../generated/resources/schema/camelYamlDsl.json   |  47 +++++
 83 files changed, 2831 insertions(+), 212 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/transform.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/transform.json
index 5e37dc5dd65..85e827be37f 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/transform.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/transform.json
@@ -13,8 +13,10 @@
   },
   "properties": {
     "expression": { "index": 0, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "secret": fa [...]
-    "disabled": { "index": 1, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "id": { "index": 2, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
-    "description": { "index": 3, "kind": "element", "displayName": "Description", "required": false, "type": "object", "javaType": "org.apache.camel.model.DescriptionDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }
+    "fromType": { "index": 1, "kind": "attribute", "displayName": "From Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "From type used in data type transformation." },
+    "toType": { "index": 2, "kind": "attribute", "displayName": "To Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To type used as a target data type in the transformation." },
+    "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
+    "id": { "index": 4, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
+    "description": { "index": 5, "kind": "element", "displayName": "Description", "required": false, "type": "object", "javaType": "org.apache.camel.model.DescriptionDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/transformers.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/transformers.json
index af5d7902054..1f2ae2ab00a 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/transformers.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/transformers.json
@@ -12,6 +12,6 @@
     "output": false
   },
   "properties": {
-    "transformers": { "index": 0, "kind": "element", "displayName": "Transformers", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.transformer.TransformerDefinition>", "oneOf": [ "customTransformer", "dataFormatTransformer", "endpointTransformer" ], "deprecated": false, "autowired": false, "secret": false, "description": "The configured transformers" }
+    "transformers": { "index": 0, "kind": "element", "displayName": "Transformers", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.transformer.TransformerDefinition>", "oneOf": [ "customTransformer", "dataFormatTransformer", "endpointTransformer", "loadTransformer" ], "deprecated": false, "autowired": false, "secret": false, "description": "The configured transformers" }
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
index 649a953edab..dc428d9a181 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
@@ -13262,6 +13262,24 @@ Sets a reference to use for lookup the policy in the registry.
           <xs:element ref="tns:xpath"/>
           <xs:element ref="tns:xquery"/>
         </xs:choice>
+        <xs:attribute name="fromType" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+From type used in data type transformation.
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="toType" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+To type used as a target data type in the transformation.
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
       </xs:extension>
     </xs:complexContent>
   </xs:complexType>
@@ -16165,6 +16183,7 @@ Sets the component name that this definition will apply to.
   <xs:complexType abstract="true" name="transformer">
     <xs:sequence/>
     <xs:attribute name="scheme" type="xs:string"/>
+    <xs:attribute name="name" type="xs:string"/>
     <xs:attribute name="fromType" type="xs:string"/>
     <xs:attribute name="toType" type="xs:string"/>
   </xs:complexType>
@@ -16227,11 +16246,21 @@ Sets the component name that this definition will apply to.
       </xs:extension>
     </xs:complexContent>
   </xs:complexType>
+  <xs:complexType name="loadTransformer">
+    <xs:complexContent>
+      <xs:extension base="tns:transformer">
+        <xs:sequence/>
+        <xs:attribute name="packageScan" type="xs:string"/>
+        <xs:attribute name="defaults" type="xs:string"/>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
   <xs:complexType name="transformersDefinition">
     <xs:sequence>
       <xs:choice maxOccurs="unbounded" minOccurs="0">
         <xs:element name="dataFormatTransformer" type="tns:dataFormatTransformer"/>
         <xs:element name="endpointTransformer" type="tns:endpointTransformer"/>
+        <xs:element name="loadTransformer" type="tns:loadTransformer"/>
         <xs:element name="customTransformer" type="tns:customTransformer"/>
       </xs:choice>
     </xs:sequence>
diff --git a/components/camel-aws/camel-aws2-s3/pom.xml b/components/camel-aws/camel-aws2-s3/pom.xml
index 91b47ced72e..3b79056ec21 100644
--- a/components/camel-aws/camel-aws2-s3/pom.xml
+++ b/components/camel-aws/camel-aws2-s3/pom.xml
@@ -55,6 +55,14 @@
             <artifactId>camel-health</artifactId>
         </dependency>
 
+        <!-- optional CloudEvent support -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-cloudevents</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+
         <!-- for testing -->
         <dependency>
             <groupId>org.apache.camel</groupId>
diff --git a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/transform/AWS2S3CloudEventDataTypeTransformer.java b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/transform/AWS2S3CloudEventDataTypeTransformer.java
new file mode 100644
index 00000000000..6d718d506a1
--- /dev/null
+++ b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/transform/AWS2S3CloudEventDataTypeTransformer.java
@@ -0,0 +1,54 @@
+/*
+ * 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.aws2.s3.transform;
+
+import java.util.Map;
+
+import org.apache.camel.Message;
+import org.apache.camel.component.aws2.s3.AWS2S3Constants;
+import org.apache.camel.component.cloudevents.CloudEvent;
+import org.apache.camel.component.cloudevents.CloudEvents;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
+
+/**
+ * Data type transformer converts AWS S3 get object response to CloudEvent v1_0 data format. The data type sets Camel
+ * specific CloudEvent headers with values extracted from AWS S3 get object response.
+ */
+@DataTypeTransformer(name = "aws2-s3:application-cloudevents")
+public class AWS2S3CloudEventDataTypeTransformer extends Transformer {
+
+    @Override
+    public void transform(Message message, DataType fromType, DataType toType) {
+        final Map<String, Object> headers = message.getHeaders();
+
+        CloudEvent cloudEvent = CloudEvents.v1_0;
+        headers.putIfAbsent(CloudEvent.CAMEL_CLOUD_EVENT_ID, message.getExchange().getExchangeId());
+        headers.putIfAbsent(CloudEvent.CAMEL_CLOUD_EVENT_VERSION, cloudEvent.version());
+        headers.put(CloudEvent.CAMEL_CLOUD_EVENT_TYPE, "org.apache.camel.event.aws.s3.getObject");
+
+        if (message.getHeaders().containsKey(AWS2S3Constants.BUCKET_NAME)) {
+            headers.put(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE,
+                    "aws.s3.bucket." + message.getHeader(AWS2S3Constants.BUCKET_NAME, String.class));
+        }
+
+        headers.put(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT, message.getHeader(AWS2S3Constants.KEY, String.class));
+        headers.put(CloudEvent.CAMEL_CLOUD_EVENT_TIME, cloudEvent.getEventTime(message.getExchange()));
+    }
+}
diff --git a/components/camel-aws/camel-aws2-s3/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/aws2-s3-application-cloudevents b/components/camel-aws/camel-aws2-s3/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/aws2-s3-application-cloudevents
new file mode 100644
index 00000000000..ec5793a97f6
--- /dev/null
+++ b/components/camel-aws/camel-aws2-s3/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/aws2-s3-application-cloudevents
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.component.aws2.s3.transform.AWS2S3CloudEventDataTypeTransformer
diff --git a/components/camel-aws/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/transform/AWS2S3CloudEventDataTypeTransformerTest.java b/components/camel-aws/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/transform/AWS2S3CloudEventDataTypeTransformerTest.java
new file mode 100644
index 00000000000..89011c482ab
--- /dev/null
+++ b/components/camel-aws/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/transform/AWS2S3CloudEventDataTypeTransformerTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.aws2.s3.transform;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.aws2.s3.AWS2S3Constants;
+import org.apache.camel.component.cloudevents.CloudEvent;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.engine.TransformerKey;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.support.DefaultExchange;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class AWS2S3CloudEventDataTypeTransformerTest {
+
+    private final DefaultCamelContext camelContext = new DefaultCamelContext();
+
+    private final AWS2S3CloudEventDataTypeTransformer transformer = new AWS2S3CloudEventDataTypeTransformer();
+
+    @Test
+    void shouldMapToCloudEvent() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setHeader(AWS2S3Constants.KEY, "test1.txt");
+        exchange.getMessage().setHeader(AWS2S3Constants.BUCKET_NAME, "myBucket");
+        exchange.getMessage().setHeader(AWS2S3Constants.CONTENT_TYPE, "text/plain");
+        exchange.getMessage().setHeader(AWS2S3Constants.CONTENT_ENCODING, StandardCharsets.UTF_8.toString());
+        exchange.getMessage().setBody(new ByteArrayInputStream("Test1".getBytes(StandardCharsets.UTF_8)));
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        Assertions.assertTrue(exchange.getMessage().hasHeaders());
+        Assertions.assertTrue(exchange.getMessage().getHeaders().containsKey(AWS2S3Constants.KEY));
+        assertEquals("org.apache.camel.event.aws.s3.getObject",
+                exchange.getMessage().getHeader(CloudEvent.CAMEL_CLOUD_EVENT_TYPE));
+        assertEquals("test1.txt", exchange.getMessage().getHeader(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT));
+        assertEquals("aws.s3.bucket.myBucket", exchange.getMessage().getHeader(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE));
+    }
+
+    @Test
+    public void shouldLookupDataTypeTransformer() throws Exception {
+        Transformer transformer = camelContext.getTransformerRegistry()
+                .resolveTransformer(new TransformerKey("aws2-s3:application-cloudevents"));
+        Assertions.assertNotNull(transformer);
+        Assertions.assertEquals(AWS2S3CloudEventDataTypeTransformer.class, transformer.getClass());
+
+    }
+}
diff --git a/components/camel-aws/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/transform/AWS2S3TransformCloudEventsTest.java b/components/camel-aws/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/transform/AWS2S3TransformCloudEventsTest.java
new file mode 100644
index 00000000000..4069f885e4a
--- /dev/null
+++ b/components/camel-aws/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/transform/AWS2S3TransformCloudEventsTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.aws2.s3.transform;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.aws2.s3.AWS2S3Constants;
+import org.apache.camel.component.aws2.s3.AWS2S3Operations;
+import org.apache.camel.component.cloudevents.CloudEvent;
+import org.apache.camel.component.cloudevents.CloudEvents;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class AWS2S3TransformCloudEventsTest extends CamelTestSupport {
+    protected MockEndpoint resultEndpoint;
+
+    @Test
+    public void testCloudEventDataTypeTransformation() throws Exception {
+        resultEndpoint.expectedBodiesReceived("Hello World!");
+
+        Exchange exchange = template.request("direct:start", new Processor() {
+            @Override
+            public void process(Exchange exchange) {
+                exchange.getMessage().setHeader(AWS2S3Constants.BUCKET_NAME, "mycamel");
+                exchange.getMessage().setHeader(AWS2S3Constants.KEY, "camel.txt");
+                exchange.getMessage().setHeader(AWS2S3Constants.S3_OPERATION, AWS2S3Operations.getObject);
+                exchange.getMessage().setBody("Hello");
+            }
+        });
+
+        resultEndpoint.assertIsSatisfied();
+        CloudEvent cloudEvent = CloudEvents.v1_0;
+        Message received = exchange.getMessage();
+        Assertions.assertEquals("org.apache.camel.event.aws.s3.getObject",
+                received.getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TYPE).http()));
+        Assertions.assertEquals("aws.s3.bucket.mycamel",
+                received.getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE).http()));
+        Assertions.assertEquals(cloudEvent.version(),
+                received.getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_VERSION).http()));
+        Assertions.assertEquals("Hello World!", received.getBody());
+    }
+
+    @Override
+    @BeforeEach
+    public void setUp() throws Exception {
+        super.setUp();
+
+        resultEndpoint = getMockEndpoint("mock:result");
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:start")
+                        .inputType("aws2-s3:application-cloudevents")
+                        .setBody(body().append(" World!"))
+                        .outputType("http:application-cloudevents")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-cloudevents/pom.xml b/components/camel-cloudevents/pom.xml
index f61eba3a973..b1900cc229e 100644
--- a/components/camel-cloudevents/pom.xml
+++ b/components/camel-cloudevents/pom.xml
@@ -44,6 +44,13 @@
             <artifactId>camel-support</artifactId>
         </dependency>
 
+        <!-- testing -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+
     </dependencies>
 
 </project>
diff --git a/components/camel-cloudevents/src/main/java/org/apache/camel/component/cloudevents/CloudEvent.java b/components/camel-cloudevents/src/main/java/org/apache/camel/component/cloudevents/CloudEvent.java
index 0193549d8f1..ba3fc3d430a 100644
--- a/components/camel-cloudevents/src/main/java/org/apache/camel/component/cloudevents/CloudEvent.java
+++ b/components/camel-cloudevents/src/main/java/org/apache/camel/component/cloudevents/CloudEvent.java
@@ -16,6 +16,10 @@
  */
 package org.apache.camel.component.cloudevents;
 
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.Collection;
 import java.util.Objects;
 import java.util.Optional;
@@ -36,6 +40,9 @@ public interface CloudEvent {
     String CAMEL_CLOUD_EVENT_EXTENSIONS = "CamelCloudEventExtensions";
     String CAMEL_CLOUD_EVENT_CONTENT_TYPE = Exchange.CONTENT_TYPE;
 
+    String DEFAULT_CAMEL_CLOUD_EVENT_TYPE = "org.apache.camel.event";
+    String DEFAULT_CAMEL_CLOUD_EVENT_SOURCE = "org.apache.camel";
+
     /**
      * The CloudEvent spec version.
      */
@@ -65,6 +72,15 @@ public interface CloudEvent {
                 .orElseThrow(() -> new IllegalArgumentException("Unable to find attribute with id: " + id));
     }
 
+    /**
+     * Construct event time from given Camel exchange.
+     */
+    default String getEventTime(Exchange exchange) {
+        final ZonedDateTime created
+                = ZonedDateTime.ofInstant(Instant.ofEpochMilli(exchange.getCreated()), ZoneId.systemDefault());
+        return DateTimeFormatter.ISO_INSTANT.format(created);
+    }
+
     /**
      * Mandatory find http attribute by id.
      */
diff --git a/components/camel-cloudevents/src/main/java/org/apache/camel/component/cloudevents/transformer/CloudEventHttpDataTypeTransformer.java b/components/camel-cloudevents/src/main/java/org/apache/camel/component/cloudevents/transformer/CloudEventHttpDataTypeTransformer.java
new file mode 100644
index 00000000000..c52c9af460e
--- /dev/null
+++ b/components/camel-cloudevents/src/main/java/org/apache/camel/component/cloudevents/transformer/CloudEventHttpDataTypeTransformer.java
@@ -0,0 +1,69 @@
+/*
+ * 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.cloudevents.transformer;
+
+import java.util.Map;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.cloudevents.CloudEvent;
+import org.apache.camel.component.cloudevents.CloudEvents;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
+
+/**
+ * Data type represents a default Camel CloudEvent V1 Http binding. The data type reads Camel specific CloudEvent
+ * headers and transforms these to Http headers according to the CloudEvents Http binding specification. Sets default
+ * values for CloudEvent attributes such as the Http content type header, event source, event type.
+ */
+@DataTypeTransformer(name = "http:application-cloudevents")
+public class CloudEventHttpDataTypeTransformer extends Transformer {
+
+    @Override
+    public void transform(Message message, DataType fromType, DataType toType) {
+        final Map<String, Object> headers = message.getHeaders();
+
+        CloudEvent cloudEvent = CloudEvents.v1_0;
+        headers.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_ID).http(),
+                headers.getOrDefault(CloudEvent.CAMEL_CLOUD_EVENT_ID, message.getExchange().getExchangeId()));
+        headers.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_VERSION).http(),
+                headers.getOrDefault(CloudEvent.CAMEL_CLOUD_EVENT_VERSION, cloudEvent.version()));
+        headers.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TYPE).http(),
+                headers.getOrDefault(CloudEvent.CAMEL_CLOUD_EVENT_TYPE, CloudEvent.DEFAULT_CAMEL_CLOUD_EVENT_TYPE));
+        headers.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE).http(),
+                headers.getOrDefault(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE, CloudEvent.DEFAULT_CAMEL_CLOUD_EVENT_SOURCE));
+
+        if (headers.containsKey(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT)) {
+            headers.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT).http(),
+                    headers.get(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT));
+        }
+
+        if (headers.containsKey(CloudEvent.CAMEL_CLOUD_EVENT_DATA_CONTENT_TYPE)) {
+            headers.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_DATA_CONTENT_TYPE).http(),
+                    headers.get(CloudEvent.CAMEL_CLOUD_EVENT_DATA_CONTENT_TYPE));
+        }
+
+        headers.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TIME).http(),
+                headers.getOrDefault(CloudEvent.CAMEL_CLOUD_EVENT_TIME, cloudEvent.getEventTime(message.getExchange())));
+        headers.putIfAbsent(Exchange.CONTENT_TYPE,
+                headers.getOrDefault(CloudEvent.CAMEL_CLOUD_EVENT_CONTENT_TYPE, "application/json"));
+
+        cloudEvent.attributes().stream().map(CloudEvent.Attribute::id).forEach(headers::remove);
+    }
+}
diff --git a/components/camel-cloudevents/src/main/java/org/apache/camel/component/cloudevents/transformer/CloudEventJsonDataTypeTransformer.java b/components/camel-cloudevents/src/main/java/org/apache/camel/component/cloudevents/transformer/CloudEventJsonDataTypeTransformer.java
new file mode 100644
index 00000000000..1eef7d27fab
--- /dev/null
+++ b/components/camel-cloudevents/src/main/java/org/apache/camel/component/cloudevents/transformer/CloudEventJsonDataTypeTransformer.java
@@ -0,0 +1,88 @@
+/*
+ * 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.cloudevents.transformer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.cloudevents.CloudEvent;
+import org.apache.camel.component.cloudevents.CloudEvents;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
+
+/**
+ * Data type represents a default Camel CloudEvent V1 Json format binding. The data type reads Camel specific CloudEvent
+ * headers and transforms these to a Json object representing the CloudEvents Json format specification. Sets default
+ * values for CloudEvent attributes such as the Http content type header, event source, event type.
+ */
+@DataTypeTransformer(name = "application-cloudevents+json")
+public class CloudEventJsonDataTypeTransformer extends Transformer {
+
+    @Override
+    public void transform(Message message, DataType fromType, DataType toType) {
+        final Map<String, Object> headers = message.getHeaders();
+
+        Map<String, Object> cloudEventAttributes = new HashMap<>();
+        CloudEvent cloudEvent = CloudEvents.v1_0;
+        for (CloudEvent.Attribute attribute : cloudEvent.attributes()) {
+            if (headers.containsKey(attribute.id())) {
+                cloudEventAttributes.put(attribute.json(), headers.get(attribute.id()));
+            }
+        }
+
+        cloudEventAttributes.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_VERSION).json(),
+                cloudEvent.version());
+        cloudEventAttributes.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_ID).json(),
+                message.getExchange().getExchangeId());
+        cloudEventAttributes.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TYPE).json(),
+                CloudEvent.DEFAULT_CAMEL_CLOUD_EVENT_TYPE);
+        cloudEventAttributes.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE).json(),
+                CloudEvent.DEFAULT_CAMEL_CLOUD_EVENT_SOURCE);
+
+        cloudEventAttributes.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TIME).json(),
+                cloudEvent.getEventTime(message.getExchange()));
+
+        cloudEventAttributes.putIfAbsent("data", message.getBody(String.class));
+        cloudEventAttributes.putIfAbsent(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_DATA_CONTENT_TYPE).json(),
+                headers.getOrDefault(CloudEvent.CAMEL_CLOUD_EVENT_CONTENT_TYPE, "application/json"));
+
+        headers.put(Exchange.CONTENT_TYPE, "application/cloudevents+json");
+
+        message.setBody(createCouldEventJsonObject(cloudEventAttributes));
+
+        cloudEvent.attributes().stream().map(CloudEvent.Attribute::id).forEach(headers::remove);
+    }
+
+    private String createCouldEventJsonObject(Map<String, Object> cloudEventAttributes) {
+        StringBuilder builder = new StringBuilder("{");
+
+        cloudEventAttributes.forEach((key, value) -> {
+            builder.append(" ").append("\"").append(key).append("\"").append(":").append("\"").append(value).append("\"")
+                    .append(",");
+        });
+
+        if (!cloudEventAttributes.isEmpty()) {
+            builder.deleteCharAt(builder.lastIndexOf(","));
+        }
+
+        return builder.append("}").toString();
+    }
+}
diff --git a/components/camel-cloudevents/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/application-cloudevents-json b/components/camel-cloudevents/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/application-cloudevents-json
new file mode 100644
index 00000000000..d380ef770b9
--- /dev/null
+++ b/components/camel-cloudevents/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/application-cloudevents-json
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.component.cloudevents.transformer.CloudEventJsonDataTypeTransformer
diff --git a/components/camel-cloudevents/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/http-application-cloudevents b/components/camel-cloudevents/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/http-application-cloudevents
new file mode 100644
index 00000000000..ca4580b0f73
--- /dev/null
+++ b/components/camel-cloudevents/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/http-application-cloudevents
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.component.cloudevents.transformer.CloudEventHttpDataTypeTransformer
diff --git a/components/camel-cloudevents/src/test/java/org/apache/camel/component/cloudevents/transformer/CloudEventHttpDataTypeTransformerTest.java b/components/camel-cloudevents/src/test/java/org/apache/camel/component/cloudevents/transformer/CloudEventHttpDataTypeTransformerTest.java
new file mode 100644
index 00000000000..d4a864a7f6a
--- /dev/null
+++ b/components/camel-cloudevents/src/test/java/org/apache/camel/component/cloudevents/transformer/CloudEventHttpDataTypeTransformerTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.cloudevents.transformer;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.cloudevents.CloudEvent;
+import org.apache.camel.component.cloudevents.CloudEvents;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.engine.TransformerKey;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.support.DefaultExchange;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class CloudEventHttpDataTypeTransformerTest {
+
+    private final DefaultCamelContext camelContext = new DefaultCamelContext();
+
+    private final CloudEventHttpDataTypeTransformer transformer = new CloudEventHttpDataTypeTransformer();
+
+    @Test
+    void shouldMapToHttpCloudEvent() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setHeader(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT, "test1.txt");
+        exchange.getMessage().setHeader(CloudEvent.CAMEL_CLOUD_EVENT_TYPE, "org.apache.camel.event.test");
+        exchange.getMessage().setHeader(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE, "org.apache.camel.test");
+        exchange.getMessage().setHeader(CloudEvent.CAMEL_CLOUD_EVENT_CONTENT_TYPE, "text/plain");
+        exchange.getMessage().setBody(new ByteArrayInputStream("Test1".getBytes(StandardCharsets.UTF_8)));
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        CloudEvent cloudEvent = CloudEvents.v1_0;
+        assertTrue(exchange.getMessage().hasHeaders());
+        assertEquals(exchange.getExchangeId(),
+                exchange.getMessage().getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_ID).http()));
+        assertEquals(cloudEvent.version(),
+                exchange.getMessage().getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_VERSION).http()));
+        assertEquals("org.apache.camel.event.test",
+                exchange.getMessage().getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TYPE).http()));
+        assertEquals("test1.txt",
+                exchange.getMessage().getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT).http()));
+        assertEquals("org.apache.camel.test",
+                exchange.getMessage().getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE).http()));
+        assertTrue(exchange.getMessage().getHeaders()
+                .containsKey(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TIME).http()));
+        assertEquals("text/plain", exchange.getMessage().getHeader(Exchange.CONTENT_TYPE));
+        assertEquals("Test1", exchange.getMessage().getBody(String.class));
+
+        assertNull(exchange.getMessage().getHeader(CloudEvent.CAMEL_CLOUD_EVENT_TYPE));
+        assertNull(exchange.getMessage().getHeader(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE));
+        assertNull(exchange.getMessage().getHeader(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT));
+    }
+
+    @Test
+    void shouldSetDefaultCloudEventAttributes() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setBody(new ByteArrayInputStream("{}".getBytes(StandardCharsets.UTF_8)));
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        CloudEvent cloudEvent = CloudEvents.v1_0;
+        assertTrue(exchange.getMessage().hasHeaders());
+        assertEquals(exchange.getExchangeId(),
+                exchange.getMessage().getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_ID).http()));
+        assertEquals(cloudEvent.version(),
+                exchange.getMessage().getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_VERSION).http()));
+        assertEquals(CloudEvent.DEFAULT_CAMEL_CLOUD_EVENT_TYPE,
+                exchange.getMessage().getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TYPE).http()));
+        assertNull(exchange.getMessage().getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT).http()));
+        assertEquals(CloudEvent.DEFAULT_CAMEL_CLOUD_EVENT_SOURCE,
+                exchange.getMessage().getHeader(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE).http()));
+        assertTrue(exchange.getMessage().getHeaders()
+                .containsKey(cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TIME).http()));
+        assertEquals("application/json", exchange.getMessage().getHeader(Exchange.CONTENT_TYPE));
+        assertEquals("{}", exchange.getMessage().getBody(String.class));
+    }
+
+    @Test
+    public void shouldLookupTransformer() throws Exception {
+        Transformer transformer
+                = camelContext.getTransformerRegistry().resolveTransformer(new TransformerKey("http:application-cloudevents"));
+        Assertions.assertNotNull(transformer);
+        Assertions.assertEquals(CloudEventHttpDataTypeTransformer.class, transformer.getClass());
+    }
+}
diff --git a/components/camel-cloudevents/src/test/java/org/apache/camel/component/cloudevents/transformer/CloudEventJsonDataTypeTransformerTest.java b/components/camel-cloudevents/src/test/java/org/apache/camel/component/cloudevents/transformer/CloudEventJsonDataTypeTransformerTest.java
new file mode 100644
index 00000000000..02b223e10a1
--- /dev/null
+++ b/components/camel-cloudevents/src/test/java/org/apache/camel/component/cloudevents/transformer/CloudEventJsonDataTypeTransformerTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.cloudevents.transformer;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.cloudevents.CloudEvent;
+import org.apache.camel.component.cloudevents.CloudEvents;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.engine.TransformerKey;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.support.DefaultExchange;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class CloudEventJsonDataTypeTransformerTest {
+
+    private final DefaultCamelContext camelContext = new DefaultCamelContext();
+
+    private final CloudEventJsonDataTypeTransformer transformer = new CloudEventJsonDataTypeTransformer();
+
+    @Test
+    void shouldMapToJsonCloudEventFormat() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setHeader(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT, "test1.txt");
+        exchange.getMessage().setHeader(CloudEvent.CAMEL_CLOUD_EVENT_TYPE, "org.apache.camel.event.test");
+        exchange.getMessage().setHeader(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE, "org.apache.camel.test");
+        exchange.getMessage().setHeader(CloudEvent.CAMEL_CLOUD_EVENT_CONTENT_TYPE, "text/plain");
+        exchange.getMessage().setBody(new ByteArrayInputStream("Test1".getBytes(StandardCharsets.UTF_8)));
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        CloudEvent cloudEvent = CloudEvents.v1_0;
+        assertTrue(exchange.getMessage().hasHeaders());
+        assertEquals("application/cloudevents+json", exchange.getMessage().getHeader(Exchange.CONTENT_TYPE));
+        assertTrue(exchange.getMessage().getBody(String.class).contains(String.format("\"%s\":\"%s\"",
+                cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_ID).json(), exchange.getExchangeId())));
+        assertTrue(exchange.getMessage().getBody(String.class).contains(String.format("\"%s\":\"org.apache.camel.event.test\"",
+                cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TYPE).json())));
+        assertTrue(exchange.getMessage().getBody(String.class).contains(String.format("\"%s\":\"org.apache.camel.test\"",
+                cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE).json())));
+        assertTrue(exchange.getMessage().getBody(String.class).contains(String.format("\"%s\":\"text/plain\"",
+                cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_DATA_CONTENT_TYPE).json())));
+        assertTrue(exchange.getMessage().getBody(String.class).contains("\"data\":\"Test1\""));
+
+        assertNull(exchange.getMessage().getHeader(CloudEvent.CAMEL_CLOUD_EVENT_TYPE));
+        assertNull(exchange.getMessage().getHeader(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE));
+        assertNull(exchange.getMessage().getHeader(CloudEvent.CAMEL_CLOUD_EVENT_SUBJECT));
+    }
+
+    @Test
+    void shouldSetDefaultCloudEventAttributes() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setBody(new ByteArrayInputStream("Test".getBytes(StandardCharsets.UTF_8)));
+
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        CloudEvent cloudEvent = CloudEvents.v1_0;
+        assertTrue(exchange.getMessage().hasHeaders());
+        assertEquals("application/cloudevents+json", exchange.getMessage().getHeader(Exchange.CONTENT_TYPE));
+        assertTrue(exchange.getMessage().getBody(String.class).contains(String.format("\"%s\":\"%s\"",
+                cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_ID).json(), exchange.getExchangeId())));
+        assertTrue(exchange.getMessage().getBody(String.class).contains(String.format("\"%s\":\"org.apache.camel.event\"",
+                cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_TYPE).json())));
+        assertTrue(exchange.getMessage().getBody(String.class).contains(String.format("\"%s\":\"org.apache.camel\"",
+                cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_SOURCE).json())));
+        assertTrue(exchange.getMessage().getBody(String.class).contains(String.format("\"%s\":\"application/json\"",
+                cloudEvent.mandatoryAttribute(CloudEvent.CAMEL_CLOUD_EVENT_DATA_CONTENT_TYPE).json())));
+        assertTrue(exchange.getMessage().getBody(String.class).contains("\"data\":\"Test\""));
+    }
+
+    @Test
+    public void shouldLookupTransformer() throws Exception {
+        Transformer transformer
+                = camelContext.getTransformerRegistry().resolveTransformer(new TransformerKey("application-cloudevents+json"));
+        Assertions.assertNotNull(transformer);
+        Assertions.assertEquals(CloudEventJsonDataTypeTransformer.class, transformer.getClass());
+    }
+}
diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/impl/transformer/SpringTransformerRouteTest.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/impl/transformer/SpringTransformerRouteTest.xml
index 47ce89a6189..319600d9bfe 100644
--- a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/impl/transformer/SpringTransformerRouteTest.xml
+++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/impl/transformer/SpringTransformerRouteTest.xml
@@ -30,16 +30,18 @@
     <bean id="otherToXOrder" class="org.apache.camel.processor.transformer.TransformerRouteTest$OtherToXOrderTransformer"/>
     <bean id="xOrderResponseToOther" class="org.apache.camel.processor.transformer.TransformerRouteTest$XOrderResponseToOtherTransformer"/>
     <bean id="myMyDataTypeFormatDef" class="org.apache.camel.processor.transformer.TransformerRouteTest$MyDataFormatDefinition"/>
-    
+
     <camelContext xmlns="http://camel.apache.org/schema/spring">
-    
+
         <endpoint id="myXmlEndpoint" uri="direct:endpointXmlTransformer"/>
 
         <transformers>
+            <loadTransformer defaults="true"/>
+            <loadTransformer packageScan="org.apache.camel.processor.transformer.custom"/>
             <dataFormatTransformer scheme="json">
                 <custom ref="myJsonDataFormatDef"/>
             </dataFormatTransformer>
-            <dataFormatTransformer scheme="myDataType">
+            <dataFormatTransformer name="myDataType">
                 <custom ref="myMyDataTypeFormatDef"/>
             </dataFormatTransformer>
             <endpointTransformer ref="myXmlEndpoint" fromType="xml:XmlXOrder" toType="java:org.apache.camel.processor.transformer.TransformerRouteTest$XOrder"/>
@@ -74,26 +76,26 @@
             <setBody><constant>response</constant></setBody>
             <to uri="mock:xyzresult"/>
         </route>
-        
+
         <route>
             <from uri="direct:dataFormat"/>
             <inputType urn="json:JsonXOrder"/>
             <outputType urn="json:JsonXOrderResponse"/>
             <to uri="direct:xyz" pattern="InOut"/>
         </route>
-        
+
         <route>
             <from uri="direct:endpoint"/>
             <inputType urn="xml:XmlXOrder"/>
             <outputType urn="xml:XmlXOrderResponse"/>
             <to uri="direct:xyz" pattern="InOut"/>
         </route>
-        
+
         <route>
             <from uri="direct:endpointXmlTransformer"/>
             <process ref="myXmlProcessor"/>
         </route>
-        
+
         <route>
             <from uri="direct:custom"/>
             <inputType urn="other:OtherXOrder"/>
@@ -114,5 +116,5 @@
         </route>
 
     </camelContext>
-  
+
 </beans>
diff --git a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
index 33cf3735b90..0a7464354ec 100644
--- a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
@@ -948,10 +948,10 @@ public interface CamelContext extends CamelContextLifecycle, RuntimeConfiguratio
     /**
      * Resolve a transformer given a scheme
      *
-     * @param  model data model name.
-     * @return       the resolved transformer, or <tt>null</tt> if not found
+     * @param  name the transformer name, usually a combination of some scheme and name.
+     * @return      the resolved transformer, or <tt>null</tt> if not found
      */
-    Transformer resolveTransformer(String model);
+    Transformer resolveTransformer(String name);
 
     /**
      * Resolve a transformer given from/to data type.
@@ -1408,8 +1408,8 @@ public interface CamelContext extends CamelContextLifecycle, RuntimeConfiguratio
     /**
      * Whether to enable using data type on Camel messages.
      * <p/>
-     * Data type are automatic turned on if one ore more routes has been explicit configured with input and output
-     * types. Otherwise data type is default off.
+     * Data type are automatic turned on if one or more routes has been explicit configured with input and output types.
+     * Otherwise, data type is default off.
      *
      * @return <tt>true</tt> if data type is enabled
      */
@@ -1418,8 +1418,8 @@ public interface CamelContext extends CamelContextLifecycle, RuntimeConfiguratio
     /**
      * Whether to enable using data type on Camel messages.
      * <p/>
-     * Data type are automatic turned on if one ore more routes has been explicit configured with input and output
-     * types. Otherwise data type is default off.
+     * Data type are automatic turned on if one or more routes has been explicit configured with input and output types.
+     * Otherwise, data type is default off.
      *
      * @param useDataType <tt>true</tt> to enable data type on Camel messages.
      */
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/DataType.java b/core/camel-api/src/main/java/org/apache/camel/spi/DataType.java
index d741a81d956..333c262b47f 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/DataType.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/DataType.java
@@ -24,10 +24,16 @@ import org.apache.camel.util.StringHelper;
  * Java class doesn't always explain the data type completely, for example XML and JSON data format is sometimes
  * serialized as a {@code String}, {@code InputStream} or etc. The {@link DataTypeAware} message stores the DataType as
  * a part of the message to carry those data type information even if it's marshaled, so that it could be leveraged to
- * detect required {@link Transformer} and {@link Validator}. DataType consists of two parts, 'model' and 'name'. Its
- * string representation is 'model:name' connected with colon. For example 'java:com.example.Order', 'xml:ABCOrder' or
- * 'json:XYZOrder'. These type name other than java class name allows the message to carry the name of the message data
- * structure even if it's marshaled.
+ * detect required {@link Transformer} and {@link Validator}. DataType URN consists of two parts, 'scheme' and 'name'.
+ *
+ * Its string representation is 'scheme:name' connected with colon. For example 'java:com.example.Order', 'xml:ABCOrder'
+ * or 'json:XYZOrder'. These type name other than java class name allows the message to carry the name of the message
+ * data structure even if it's marshaled.
+ * <p/>
+ * The scheme can also be used to associate the same DataType with different Camel components. For example
+ * `http:cloud-events` and `aws-s3:cloud-events` where the scheme relates to the respective component's scheme. This
+ * information could be leveraged to detect required {@link Transformer} and {@link Validator} implementations provided
+ * as part of these components.
  *
  * @see DataTypeAware
  * @see Transformer
@@ -35,9 +41,13 @@ import org.apache.camel.util.StringHelper;
  */
 public class DataType {
 
-    public static final String JAVA_TYPE_PREFIX = "java";
+    public static final String DEFAULT_SCHEME = "camel";
+    public static final String JAVA_TYPE_SCHEME = "java";
+
+    public static final String ANY_TYPE_URN = DEFAULT_SCHEME + ":any";
+    public static final DataType ANY = new DataType(ANY_TYPE_URN);
 
-    private String model;
+    private final String scheme;
     private String name;
     private boolean isJavaType;
     private String typeString;
@@ -45,28 +55,35 @@ public class DataType {
     public DataType(String urn) {
         if (urn != null) {
             String[] split = StringHelper.splitOnCharacter(urn, ":", 2);
-            model = split[0];
-            isJavaType = model.equals(JAVA_TYPE_PREFIX);
+            scheme = split[0];
+            isJavaType = scheme.equals(JAVA_TYPE_SCHEME);
             if (split.length > 1) {
                 name = split[1];
             }
+        } else {
+            scheme = DataType.ANY.scheme;
+            name = DataType.ANY.name;
         }
     }
 
     public DataType(Class<?> clazz) {
-        model = JAVA_TYPE_PREFIX;
+        scheme = JAVA_TYPE_SCHEME;
         isJavaType = true;
         name = clazz.getName();
     }
 
-    public String getModel() {
-        return model;
+    public String getScheme() {
+        return scheme;
     }
 
     public String getName() {
         return name;
     }
 
+    public String getFullName() {
+        return name != null && !name.isEmpty() ? scheme + ":" + name : scheme;
+    }
+
     public boolean isJavaType() {
         return isJavaType;
     }
@@ -74,23 +91,31 @@ public class DataType {
     @Override
     public String toString() {
         if (this.typeString == null) {
-            this.typeString = name != null && !name.isEmpty() ? model + ":" + name : model;
+            this.typeString = getFullName();
         }
         return this.typeString;
     }
 
+    public static boolean isAnyType(DataType dataType) {
+        return dataType == null || DataType.ANY.equals(dataType);
+    }
+
+    public static boolean isJavaType(DataType dataType) {
+        return dataType != null && dataType.isJavaType();
+    }
+
     @Override
     public boolean equals(Object target) {
         if (target instanceof DataType) {
             DataType targetdt = (DataType) target;
-            String targetModel = targetdt.getModel();
+            String targetScheme = targetdt.getScheme();
             String targetName = targetdt.getName();
-            if (targetModel == null) {
+            if (targetScheme == null) {
                 return false;
             } else if (targetName == null) {
-                return targetModel.equals(getModel()) && getName() == null;
+                return targetScheme.equals(getScheme()) && getName() == null;
             } else {
-                return targetModel.equals(getModel()) && targetName.equals(getName());
+                return targetScheme.equals(getScheme()) && targetName.equals(getName());
             }
         }
         return false;
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/DataTypeTransformer.java b/core/camel-api/src/main/java/org/apache/camel/spi/DataTypeTransformer.java
new file mode 100644
index 00000000000..b047ed367bd
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/DataTypeTransformer.java
@@ -0,0 +1,60 @@
+/*
+ * 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.spi;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to configure a data type transformer with either specifying its name or from/to data types.
+ * <p/>
+ * The annotation is used by specific classpath scanning data type loaders to automatically add the data types to a
+ * registry.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ ElementType.TYPE })
+public @interface DataTypeTransformer {
+
+    /**
+     * Data type transformer name. Identifies the data type transformer. Should be unique in the Camel context. Can be a
+     * combination of scheme and name. Is used to detect/reference the transformer when specifying input/output data
+     * types on routes.
+     *
+     * @return the data type transformer name.
+     */
+    String name() default "";
+
+    /**
+     * Data type representing the input of the transformation. Also used to detect the transformer.
+     *
+     * @return
+     */
+    String fromType() default "";
+
+    /**
+     * Data type representing the result of the transformation. Also used to detect the transformer.
+     *
+     * @return
+     */
+    String toType() default "";
+
+}
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Transformer.java b/core/camel-api/src/main/java/org/apache/camel/spi/Transformer.java
index 814143a0869..b730fe5af12 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/Transformer.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/Transformer.java
@@ -20,6 +20,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.Message;
 import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.ObjectHelper;
 
 /**
  * <a href="http://camel.apache.org/transformer.html">Transformer</a> performs message transformation according to the
@@ -32,10 +33,31 @@ import org.apache.camel.support.service.ServiceSupport;
 public abstract class Transformer extends ServiceSupport implements CamelContextAware {
 
     private CamelContext camelContext;
-    private String model;
+    private String name;
     private DataType from;
     private DataType to;
 
+    public Transformer() {
+        if (this.getClass().isAnnotationPresent(DataTypeTransformer.class)) {
+            DataTypeTransformer annotation = this.getClass().getAnnotation(DataTypeTransformer.class);
+            if (ObjectHelper.isNotEmpty(annotation.name())) {
+                this.name = annotation.name();
+            }
+
+            if (ObjectHelper.isNotEmpty(annotation.fromType())) {
+                this.from = new DataType(annotation.fromType());
+            }
+
+            if (ObjectHelper.isNotEmpty(annotation.toType())) {
+                this.to = new DataType(annotation.toType());
+            }
+        }
+    }
+
+    public Transformer(String name) {
+        this.name = name;
+    }
+
     /**
      * Perform data transformation with specified from/to type.
      *
@@ -46,10 +68,12 @@ public abstract class Transformer extends ServiceSupport implements CamelContext
     public abstract void transform(Message message, DataType from, DataType to) throws Exception;
 
     /**
-     * Get a data model which is supported by this transformer.
+     * Get the transformer name that represents the supported data type model.
+     *
+     * @return
      */
-    public String getModel() {
-        return model;
+    public String getName() {
+        return name;
     }
 
     /**
@@ -67,12 +91,32 @@ public abstract class Transformer extends ServiceSupport implements CamelContext
     }
 
     /**
-     * Set data model.
+     * Set the name for this transformer. Usually a combination of scheme and name.
+     *
+     * @param name the transformer name
+     */
+    public Transformer setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    /**
+     * Set the scheme and/or name for this transformer. When using only a scheme the transformer applies to all
+     * transformations with that scheme.
      *
-     * @param model data model
+     * @param scheme supported data type scheme
+     * @param name   transformer name
      */
-    public Transformer setModel(String model) {
-        this.model = model;
+    public Transformer setName(String scheme, String name) {
+        if (ObjectHelper.isNotEmpty(scheme)) {
+            if (ObjectHelper.isNotEmpty(name)) {
+                this.name = scheme + ":" + name;
+            } else {
+                this.name = scheme;
+            }
+        } else {
+            this.name = name;
+        }
         return this;
     }
 
@@ -108,7 +152,7 @@ public abstract class Transformer extends ServiceSupport implements CamelContext
 
     @Override
     public String toString() {
-        return String.format("%s[scheme='%s', from='%s', to='%s']", this.getClass().getSimpleName(), model, from, to);
+        return String.format("%s[name='%s', from='%s', to='%s']", this.getClass().getSimpleName(), name, from, to);
     }
 
     @Override
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java b/core/camel-api/src/main/java/org/apache/camel/spi/TransformerLoader.java
similarity index 65%
copy from core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
copy to core/camel-api/src/main/java/org/apache/camel/spi/TransformerLoader.java
index 23827554acc..16f46d5754a 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/TransformerLoader.java
@@ -14,16 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.api.management.mbean;
 
-import org.apache.camel.api.management.ManagedAttribute;
+package org.apache.camel.spi;
 
-public interface ManagedTransformMBean extends ManagedProcessorMBean {
-
-    @ManagedAttribute(description = "The language for the expression")
-    String getExpressionLanguage();
+/**
+ * A pluggable strategy to load data types into a {@link TransformerRegistry}. Loads one to many data type transformers
+ * to the given registry.
+ */
+public interface TransformerLoader {
 
-    @ManagedAttribute(description = "Expression to return the transformed message body (the new message body to use)")
-    String getExpression();
+    /**
+     * A pluggable strategy to load transformers into a given registry.
+     *
+     * @param registry the registry the transformers get added to.
+     */
+    void load(TransformerRegistry registry);
 
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/TransformerResolver.java b/core/camel-api/src/main/java/org/apache/camel/spi/TransformerResolver.java
new file mode 100644
index 00000000000..cf03dc13012
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/TransformerResolver.java
@@ -0,0 +1,54 @@
+/*
+ * 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.spi;
+
+import java.util.Locale;
+
+import org.apache.camel.CamelContext;
+
+/**
+ * Resolves data type transformers from given transformer key. This represents the opportunity to lazy load transformers
+ * via factory finder discovery mechanism.
+ */
+@FunctionalInterface
+public interface TransformerResolver<K> {
+
+    /**
+     * Attempts to resolve the transformer for the given key. Usually uses the factory finder URI to resolve the
+     * transformer by its name derived from the given key. Transformer names may use scheme and name as a combination in
+     * order to resolve component specific transformers. Usually implements a fallback resolving mechanism when no
+     * matching transformer is found (e.g. search for generic Camel transformers just using the name).
+     *
+     * @param  key          the transformer key.
+     * @param  camelContext the current Camel context.
+     * @return              data type transformer resolved via URI factory finder or null if not found.
+     */
+    Transformer resolve(K key, CamelContext camelContext);
+
+    /**
+     * Normalize transformer key to conform with factory finder resource path. Replaces all non supported characters
+     * such as slashes and colons to dashes.
+     *
+     * @param  key the transformer key
+     * @return     normalized String representation of the key
+     */
+    default String normalize(K key) {
+        return key.toString().replaceAll("[^A-Za-z0-9-]", "-").toLowerCase(Locale.US);
+    }
+
+}
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index e22568d641e..a282225893c 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -3867,8 +3867,8 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     @Override
-    public Transformer resolveTransformer(String scheme) {
-        return getTransformerRegistry().resolveTransformer(new TransformerKey(scheme));
+    public Transformer resolveTransformer(String name) {
+        return getTransformerRegistry().resolveTransformer(new TransformerKey(name));
     }
 
     @Override
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerRegistry.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerRegistry.java
index 23000c889df..cf3f8942e03 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerRegistry.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerRegistry.java
@@ -20,12 +20,17 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
 import org.apache.camel.spi.DataType;
 import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.TransformerLoader;
 import org.apache.camel.spi.TransformerRegistry;
+import org.apache.camel.spi.TransformerResolver;
 import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.service.ServiceHelper;
 import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Default implementation of {@link org.apache.camel.spi.TransformerRegistry}.
@@ -33,8 +38,12 @@ import org.apache.camel.util.ObjectHelper;
 public class DefaultTransformerRegistry extends AbstractDynamicRegistry<TransformerKey, Transformer>
         implements TransformerRegistry<TransformerKey> {
 
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultTransformerRegistry.class);
+
     private final Map<TransformerKey, TransformerKey> aliasMap;
 
+    private TransformerResolver<TransformerKey> transformerResolver;
+
     public DefaultTransformerRegistry(CamelContext context) {
         super(context, CamelContextHelper.getMaximumTransformerCacheSize(context));
         this.aliasMap = new ConcurrentHashMap<>();
@@ -42,41 +51,107 @@ public class DefaultTransformerRegistry extends AbstractDynamicRegistry<Transfor
 
     @Override
     public Transformer resolveTransformer(TransformerKey key) {
-        if (ObjectHelper.isEmpty(key.getScheme()) && key.getTo() == null) {
+        if (DataType.isAnyType(key.getFrom()) && DataType.isAnyType(key.getTo())) {
             return null;
         }
 
         // try exact match
         Transformer answer = get(aliasMap.getOrDefault(key, key));
-        if (answer != null || ObjectHelper.isNotEmpty(key.getScheme())) {
+        if (answer != null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Found transformer {} for key {}", ObjectHelper.name(answer.getClass()), key);
+            }
+
             return answer;
         }
 
-        // try wildcard match for next - add an alias if matched
+        // try wildcard match for transformers with matching data type scheme - add an alias if matched
         TransformerKey alias = null;
-        if (key.getFrom() != null && ObjectHelper.isNotEmpty(key.getFrom().getName())) {
-            alias = new TransformerKey(new DataType(key.getFrom().getModel()), key.getTo());
+        if (!DataType.isAnyType(key.getFrom()) && ObjectHelper.isNotEmpty(key.getFrom().getName())) {
+            alias = new TransformerKey(new DataType(key.getFrom().getScheme()), key.getTo());
             answer = get(alias);
         }
         if (answer == null && ObjectHelper.isNotEmpty(key.getTo().getName())) {
-            alias = new TransformerKey(key.getFrom(), new DataType(key.getTo().getModel()));
+            alias = new TransformerKey(key.getFrom(), new DataType(key.getTo().getScheme()));
             answer = get(alias);
         }
-        if (answer == null && key.getFrom() != null && ObjectHelper.isNotEmpty(key.getFrom().getName())
+        if (answer == null && !DataType.isAnyType(key.getFrom()) && ObjectHelper.isNotEmpty(key.getFrom().getName())
                 && ObjectHelper.isNotEmpty(key.getTo().getName())) {
-            alias = new TransformerKey(new DataType(key.getFrom().getModel()), new DataType(key.getTo().getModel()));
+            alias = new TransformerKey(new DataType(key.getFrom().getScheme()), new DataType(key.getTo().getScheme()));
             answer = get(alias);
         }
-        if (answer == null && key.getFrom() != null) {
-            alias = new TransformerKey(key.getFrom().getModel());
+
+        if (answer == null && !DataType.isAnyType(key.getTo())) {
+            alias = new TransformerKey(key.getTo());
             answer = get(alias);
+
+            if (answer == null) {
+                alias = new TransformerKey(key.getTo().getScheme());
+                answer = get(alias);
+            }
         }
-        if (answer == null) {
-            alias = new TransformerKey(key.getTo().getModel());
+
+        if (answer == null && !DataType.isAnyType(key.getFrom())) {
+            alias = new TransformerKey(key.getFrom());
             answer = get(alias);
+
+            if (answer == null) {
+                alias = new TransformerKey(key.getFrom().getScheme());
+                answer = get(alias);
+            }
         }
+
         if (answer != null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Found transformer {} for key {} using alias {}", ObjectHelper.name(answer.getClass()), key, alias);
+            }
+
             aliasMap.put(key, alias);
+            return answer;
+        }
+
+        if (!DataType.isJavaType(key.getTo())) {
+            answer = lazyLoadTransformer(new TransformerKey(key.getTo()));
+
+            if (answer != null) {
+                // Add lazy loaded transformer and an alias
+                TransformerKey transformerKey = TransformerKey.createFrom(answer);
+                put(transformerKey, answer);
+                if (!key.equals(transformerKey)) {
+                    aliasMap.put(key, transformerKey);
+                }
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found transformer {} for key {}", ObjectHelper.name(answer.getClass()), key);
+                }
+            }
+        }
+
+        return answer;
+    }
+
+    /**
+     * Tra to lazy load transformer either from Camel context as bean reference or via transformer resolver mechanism,
+     * e.g. doing a resource path lookup.
+     *
+     * @param  key the transformer key.
+     * @return     lazy loaded transformer or null if not found.
+     */
+    private Transformer lazyLoadTransformer(TransformerKey key) {
+        // Looking for matching beans in Camel registry first
+        Transformer answer = CamelContextHelper.lookup(context, key.toString(), Transformer.class);
+
+        if (answer == null) {
+            if (transformerResolver == null) {
+                TransformerResolver<?> contextResolver = context.getRegistry().findSingleByType(TransformerResolver.class);
+                if (contextResolver != null) {
+                    transformerResolver = (TransformerResolver<TransformerKey>) contextResolver;
+                } else {
+                    transformerResolver = new DefaultTransformerResolver();
+                }
+            }
+
+            // Try to lazy load transformer via resolver, e.g. with resource path lookup
+            answer = transformerResolver.resolve(key, context);
         }
 
         return answer;
@@ -86,7 +161,27 @@ public class DefaultTransformerRegistry extends AbstractDynamicRegistry<Transfor
     public Transformer put(TransformerKey key, Transformer obj) {
         // ensure transformer is started before its being used
         ServiceHelper.startService(obj);
-        return super.put(key, obj);
+
+        if (obj instanceof TransformerLoader) {
+            ((TransformerLoader) obj).load(this);
+            return obj;
+        } else {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Adding transformer for key {}", key);
+            }
+
+            return super.put(key, obj);
+        }
+    }
+
+    @Override
+    public void init() {
+        // if applicable set Camel context on all transformers
+        values().forEach(t -> {
+            if (((CamelContextAware) t).getCamelContext() == null) {
+                CamelContextAware.trySetCamelContext(t, context);
+            }
+        });
     }
 
     @Override
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerResolver.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerResolver.java
new file mode 100644
index 00000000000..6099e79ca31
--- /dev/null
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerResolver.java
@@ -0,0 +1,65 @@
+/*
+ * 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.impl.engine;
+
+import java.util.Optional;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.TransformerResolver;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The default implementation of {@link org.apache.camel.spi.TransformerResolver} which tries to find components by
+ * using the URI scheme prefix and searching for a file of the URI scheme name in the
+ * <b>META-INF/services/org/apache/camel/datatype/transformer/</b> directory on the classpath.
+ */
+public class DefaultTransformerResolver implements TransformerResolver<TransformerKey> {
+
+    public static final String DATA_TYPE_TRANSFORMER_RESOURCE_PATH = "META-INF/services/org/apache/camel/datatype/transformer/";
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultTransformerResolver.class);
+
+    @Override
+    public Transformer resolve(TransformerKey key, CamelContext context) {
+        String normalizedKey = normalize(key);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Resolving data type transformer for key {} via: {}{}", key, DATA_TYPE_TRANSFORMER_RESOURCE_PATH,
+                    normalizedKey);
+        }
+
+        Optional<Transformer> transformer = findTransformer(normalizedKey, context);
+        if (LOG.isDebugEnabled() && transformer.isPresent()) {
+            LOG.debug("Found data type transformer for key {} via type: {} via: {}{}", key,
+                    ObjectHelper.name(transformer.getClass()), DATA_TYPE_TRANSFORMER_RESOURCE_PATH, normalizedKey);
+        }
+
+        transformer.ifPresent(t -> CamelContextAware.trySetCamelContext(t, context));
+
+        return transformer.orElse(null);
+    }
+
+    private Optional<Transformer> findTransformer(String key, CamelContext context) {
+        return context.getCamelContextExtension()
+                .getBootstrapFactoryFinder(DATA_TYPE_TRANSFORMER_RESOURCE_PATH)
+                .newInstance(key, Transformer.class);
+    }
+}
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultValidatorRegistry.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultValidatorRegistry.java
index 1314e058166..ef114820264 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultValidatorRegistry.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultValidatorRegistry.java
@@ -38,7 +38,7 @@ public class DefaultValidatorRegistry extends AbstractDynamicRegistry<ValidatorK
     public Validator resolveValidator(ValidatorKey key) {
         Validator answer = get(key);
         if (answer == null && ObjectHelper.isNotEmpty(key.getType().getName())) {
-            answer = get(new ValidatorKey(new DataType(key.getType().getModel())));
+            answer = get(new ValidatorKey(new DataType(key.getType().getScheme())));
         }
         return answer;
     }
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/TransformerKey.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/TransformerKey.java
index 8ce756b7d65..a74724467ef 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/TransformerKey.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/TransformerKey.java
@@ -18,6 +18,7 @@ package org.apache.camel.impl.engine;
 
 import org.apache.camel.ValueHolder;
 import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Transformer;
 import org.apache.camel.util.StringHelper;
 
 /**
@@ -26,14 +27,16 @@ import org.apache.camel.util.StringHelper;
  */
 public final class TransformerKey extends ValueHolder<String> {
 
-    private String scheme;
-    private DataType from;
-    private DataType to;
+    private final DataType from;
+    private final DataType to;
 
-    public TransformerKey(String scheme) {
-        super(scheme);
-        StringHelper.notEmpty(scheme, "scheme");
-        this.scheme = scheme;
+    public TransformerKey(String toType) {
+        this(DataType.ANY, new DataType(toType));
+        StringHelper.notEmpty(toType, "toType");
+    }
+
+    public TransformerKey(DataType to) {
+        this(DataType.ANY, to);
     }
 
     public TransformerKey(DataType from, DataType to) {
@@ -42,12 +45,35 @@ public final class TransformerKey extends ValueHolder<String> {
         this.to = to;
     }
 
+    /**
+     * Create the string that represents this transformer key. Either uses both full names of from/to data types in
+     * combination or only uses the toType data type full name in case fromType is not specified.
+     *
+     * @param  from
+     * @param  to
+     * @return
+     */
     private static String createKeyString(DataType from, DataType to) {
-        return from + "/" + to;
+        if (DataType.isAnyType(from)) {
+            return to.getFullName();
+        }
+
+        return from.getFullName() + "/" + to.getFullName();
     }
 
-    public String getScheme() {
-        return scheme;
+    /**
+     * Create the transformer key for the given transformer either using the transformer name or it's specified from/to
+     * data type name.
+     *
+     * @param  answer
+     * @return
+     */
+    public static TransformerKey createFrom(Transformer answer) {
+        if (!DataType.isAnyType(answer.getFrom()) && !DataType.isAnyType(answer.getTo())) {
+            return new TransformerKey(answer.getFrom(), answer.getTo());
+        }
+
+        return new TransformerKey(answer.getName());
     }
 
     public DataType getFrom() {
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 7a38fe8f0b4..15a4a6165bb 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -922,9 +922,15 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
     }
 
     private static ValueHolder<String> createTransformerKey(TransformerDefinition def) {
-        return ObjectHelper.isNotEmpty(def.getScheme())
-                ? new TransformerKey(def.getScheme())
-                : new TransformerKey(new DataType(def.getFromType()), new DataType(def.getToType()));
+        if (ObjectHelper.isNotEmpty(def.getScheme())) {
+            return ObjectHelper.isNotEmpty(def.getName())
+                    ? new TransformerKey(def.getScheme() + ":" + def.getName()) : new TransformerKey(def.getScheme());
+        }
+        if (ObjectHelper.isNotEmpty(def.getName())) {
+            return new TransformerKey(def.getName());
+        } else {
+            return new TransformerKey(new DataType(def.getFromType()), new DataType(def.getToType()));
+        }
     }
 
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/transform.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/transform.json
index 5e37dc5dd65..85e827be37f 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/transform.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/transform.json
@@ -13,8 +13,10 @@
   },
   "properties": {
     "expression": { "index": 0, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "secret": fa [...]
-    "disabled": { "index": 1, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "id": { "index": 2, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
-    "description": { "index": 3, "kind": "element", "displayName": "Description", "required": false, "type": "object", "javaType": "org.apache.camel.model.DescriptionDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }
+    "fromType": { "index": 1, "kind": "attribute", "displayName": "From Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "From type used in data type transformation." },
+    "toType": { "index": 2, "kind": "attribute", "displayName": "To Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To type used as a target data type in the transformation." },
+    "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
+    "id": { "index": 4, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
+    "description": { "index": 5, "kind": "element", "displayName": "Description", "required": false, "type": "object", "javaType": "org.apache.camel.model.DescriptionDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/transformer/jaxb.index b/core/camel-core-model/src/generated/resources/org/apache/camel/model/transformer/jaxb.index
index af780ec37f0..73ef81d1fb4 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/transformer/jaxb.index
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/transformer/jaxb.index
@@ -2,5 +2,6 @@
 CustomTransformerDefinition
 DataFormatTransformerDefinition
 EndpointTransformerDefinition
+LoadTransformerDefinition
 TransformerDefinition
 TransformersDefinition
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/transformer/transformers.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/transformer/transformers.json
index af5d7902054..1f2ae2ab00a 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/transformer/transformers.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/transformer/transformers.json
@@ -12,6 +12,6 @@
     "output": false
   },
   "properties": {
-    "transformers": { "index": 0, "kind": "element", "displayName": "Transformers", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.transformer.TransformerDefinition>", "oneOf": [ "customTransformer", "dataFormatTransformer", "endpointTransformer" ], "deprecated": false, "autowired": false, "secret": false, "description": "The configured transformers" }
+    "transformers": { "index": 0, "kind": "element", "displayName": "Transformers", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.transformer.TransformerDefinition>", "oneOf": [ "customTransformer", "dataFormatTransformer", "endpointTransformer", "loadTransformer" ], "deprecated": false, "autowired": false, "secret": false, "description": "The configured transformers" }
   }
 }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/TransformerBuilder.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/TransformerBuilder.java
index a1a9ec74b7d..026939d1af3 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/builder/TransformerBuilder.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/TransformerBuilder.java
@@ -22,9 +22,11 @@ import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.transformer.CustomTransformerDefinition;
 import org.apache.camel.model.transformer.DataFormatTransformerDefinition;
 import org.apache.camel.model.transformer.EndpointTransformerDefinition;
+import org.apache.camel.model.transformer.LoadTransformerDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.spi.DataType;
 import org.apache.camel.spi.Transformer;
+import org.apache.camel.util.ObjectHelper;
 
 /**
  * A <a href="http://camel.apache.org/dsl.html">Java DSL</a> which is used to build a
@@ -35,16 +37,32 @@ import org.apache.camel.spi.Transformer;
 public class TransformerBuilder {
 
     private String scheme;
+    private String name;
     private String from;
     private String to;
     private String uri;
     private DataFormatDefinition dataFormat;
     private Class<? extends Transformer> clazz;
     private String beanRef;
+    private boolean defaults;
+    private String packageScan;
+
+    /**
+     * Set the transformer name under which the transformer gets referenced when specifying the input/output data type
+     * on routes. If you specify a transformer name that matches a data type scheme like 'csv' the transformer will be
+     * picked up for all of 'csv:*' from/to Java transformation. Note that the scheme matching is performed only when no
+     * exactly matched transformer exists.
+     *
+     * @param name transformer name
+     */
+    public TransformerBuilder name(String name) {
+        this.name = name;
+        return this;
+    }
 
     /**
      * Set the scheme name supported by the transformer. If you specify 'csv', the transformer will be picked up for all
-     * of 'csv' from/to Java transformation. Note that the scheme matching is performed only when no exactly matched
+     * of 'csv:*' from/to Java transformation. Note that the scheme matching is performed only when no exactly matched
      * transformer exists.
      *
      * @param scheme scheme name
@@ -136,11 +154,33 @@ public class TransformerBuilder {
         return this;
     }
 
+    /**
+     * Enables default transformers on the registry.
+     */
+    public TransformerBuilder withDefaults() {
+        resetType();
+        this.defaults = true;
+        return this;
+    }
+
+    /**
+     * Set the classpath location to scan for {@code Transformer} implementations. Usually these transformer
+     * implementations use {@code DataTypeTransformer} annotations to expose a transformer name and supported from/to
+     * data types.
+     */
+    public TransformerBuilder scan(String location) {
+        resetType();
+        this.packageScan = location;
+        return this;
+    }
+
     private void resetType() {
         this.uri = null;
         this.dataFormat = null;
         this.clazz = null;
         this.beanRef = null;
+        this.defaults = false;
+        this.packageScan = null;
     }
 
     /**
@@ -167,12 +207,23 @@ public class TransformerBuilder {
             CustomTransformerDefinition ctd = new CustomTransformerDefinition();
             ctd.setRef(beanRef);
             transformer = ctd;
+        } else if (defaults) {
+            LoadTransformerDefinition ltd = new LoadTransformerDefinition();
+            ltd.setDefaults("true");
+            transformer = ltd;
+        } else if (packageScan != null) {
+            LoadTransformerDefinition ltd = new LoadTransformerDefinition();
+            ltd.setPackageScan(packageScan);
+            transformer = ltd;
         } else {
             throw new IllegalArgumentException("No Transformer type was specified");
         }
 
-        if (scheme != null) {
+        if (ObjectHelper.isNotEmpty(scheme)) {
             transformer.setScheme(scheme);
+            transformer.setName(name);
+        } else if (ObjectHelper.isNotEmpty(name)) {
+            transformer.setName(name);
         } else {
             transformer.setFromType(from);
             transformer.setToType(to);
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
index e766c76f42b..11ff1d8dced 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
@@ -62,6 +62,7 @@ import org.apache.camel.resume.ResumeStrategy;
 import org.apache.camel.spi.AsEndpointUri;
 import org.apache.camel.spi.AsPredicate;
 import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.DataType;
 import org.apache.camel.spi.IdempotentRepository;
 import org.apache.camel.spi.InterceptStrategy;
 import org.apache.camel.spi.Metadata;
@@ -2453,6 +2454,33 @@ public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type>
         return asType();
     }
 
+    /**
+     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> Adds a processor which sets
+     * the body on the OUT message according to a data type transformation.
+     *
+     * @param  fromType the data type representing the input of the transformation
+     * @param  toType   the data type representing the output of the transformation.
+     * @return          the builder
+     */
+    public Type transform(DataType fromType, DataType toType) {
+        TransformDefinition answer = new TransformDefinition(fromType, toType);
+        addOutput(answer);
+        return asType();
+    }
+
+    /**
+     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> Adds a processor which sets
+     * the body on the OUT message according to a data type transformation.
+     *
+     * @param  toType the data type representing the output of the transformation.
+     * @return        the builder
+     */
+    public Type transform(DataType toType) {
+        TransformDefinition answer = new TransformDefinition(DataType.ANY, toType);
+        addOutput(answer);
+        return asType();
+    }
+
     /**
      * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> Adds a processor which sets
      * the body on the OUT message
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/TransformDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/TransformDefinition.java
index e53dea89b88..a6519b5de3c 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/TransformDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/TransformDefinition.java
@@ -18,10 +18,12 @@ package org.apache.camel.model;
 
 import jakarta.xml.bind.annotation.XmlAccessType;
 import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
 import jakarta.xml.bind.annotation.XmlRootElement;
 
 import org.apache.camel.Expression;
 import org.apache.camel.model.language.ExpressionDefinition;
+import org.apache.camel.spi.DataType;
 import org.apache.camel.spi.Metadata;
 
 /**
@@ -32,6 +34,12 @@ import org.apache.camel.spi.Metadata;
 @XmlAccessorType(XmlAccessType.FIELD)
 public class TransformDefinition extends ExpressionNode {
 
+    @XmlAttribute
+    private String fromType;
+
+    @XmlAttribute
+    private String toType;
+
     public TransformDefinition() {
     }
 
@@ -39,8 +47,21 @@ public class TransformDefinition extends ExpressionNode {
         super(expression);
     }
 
+    public TransformDefinition(DataType fromType, DataType toType) {
+        this.fromType = fromType.getFullName();
+        this.toType = toType.getFullName();
+    }
+
     @Override
     public String toString() {
+        if (toType != null) {
+            if (fromType != null) {
+                return "Transform[" + fromType + ", " + toType + "]";
+            } else {
+                return "Transform[" + toType + "]";
+            }
+        }
+
         return "Transform[" + getExpression() + "]";
     }
 
@@ -51,6 +72,14 @@ public class TransformDefinition extends ExpressionNode {
 
     @Override
     public String getLabel() {
+        if (toType != null) {
+            if (fromType != null) {
+                return "transform[" + fromType + ", " + toType + "]";
+            } else {
+                return "transform[" + toType + "]";
+            }
+        }
+
         return "transform[" + getExpression() + "]";
     }
 
@@ -63,4 +92,25 @@ public class TransformDefinition extends ExpressionNode {
         super.setExpression(expression);
     }
 
+    /**
+     * From type used in data type transformation.
+     */
+    public void setFromType(String fromType) {
+        this.fromType = fromType;
+    }
+
+    public String getFromType() {
+        return fromType;
+    }
+
+    /**
+     * To type used as a target data type in the transformation.
+     */
+    public void setToType(String toType) {
+        this.toType = toType;
+    }
+
+    public String getToType() {
+        return toType;
+    }
 }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/LoadTransformerDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/LoadTransformerDefinition.java
new file mode 100644
index 00000000000..68a2630d392
--- /dev/null
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/LoadTransformerDefinition.java
@@ -0,0 +1,64 @@
+/*
+ * 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.model.transformer;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+import jakarta.xml.bind.annotation.XmlType;
+
+import org.apache.camel.spi.Metadata;
+
+/**
+ * Loads one to many {@link org.apache.camel.spi.Transformer} via {@link org.apache.camel.spi.TransformerLoader}.
+ * Supports classpath scan to load transformer implementations configured for instance via annotation configuration.
+ */
+@Metadata(label = "transformation")
+@XmlType(name = "loadTransformer")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class LoadTransformerDefinition extends TransformerDefinition {
+
+    @XmlAttribute
+    private String packageScan;
+
+    @XmlAttribute
+    @Metadata(javaType = "java.lang.Boolean", defaultValue = "false")
+    private String defaults;
+
+    public String getDefaults() {
+        return defaults;
+    }
+
+    /**
+     * Enable loading of default transformers.
+     */
+    public void setDefaults(String defaults) {
+        this.defaults = defaults;
+    }
+
+    public String getPackageScan() {
+        return packageScan;
+    }
+
+    /**
+     * Set the classpath location to scan for annotated transformers.
+     */
+    public void setPackageScan(String packageScan) {
+        this.packageScan = packageScan;
+    }
+
+}
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/TransformerDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/TransformerDefinition.java
index ef186710526..8006181630a 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/TransformerDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/TransformerDefinition.java
@@ -32,8 +32,15 @@ import org.apache.camel.spi.Metadata;
  *
  * If you specify from='java:com.example.ABC' and to='xml:XYZ', the transformer will be picked up when current message
  * type is 'java:com.example.ABC' and expected message type is 'xml:XYZ'. If you specify from='java' to='xml', then it
- * will be picked up for all of Java to xml transformation. Also it's possible to specify scheme='xml' so that the
- * transformer will be picked up for all of Java to xml and xml to java transformation.
+ * will be picked up for all of Java to xml transformation.
+ *
+ * Also, it's possible to specify a transformer name that identifies the transformer. Usually the name is a combination
+ * of a scheme and a name that represents the supported data type name. The declared {@link InputTypeDefinition} and/or
+ * {@link OutputTypeDefinition} can then reference the transformer by its name.
+ *
+ * In case the transformer name should represent a data type scheme such as name='xml' that specific transformer will
+ * also be picked up for all of Java to xml and xml to Java transformation as a fallback when no matching transformer is
+ * found.
  */
 @Metadata(label = "transformation")
 @XmlType(name = "transformer")
@@ -43,6 +50,8 @@ public abstract class TransformerDefinition {
     @XmlAttribute
     private String scheme;
     @XmlAttribute
+    private String name;
+    @XmlAttribute
     private String fromType;
     @XmlAttribute
     private String toType;
@@ -56,12 +65,28 @@ public abstract class TransformerDefinition {
      * of 'csv' from/to Java transformation. Note that the scheme matching is performed only when no exactly matched
      * transformer exists.
      *
-     * @param scheme scheme name
+     * @param scheme the supported data type scheme
      */
     public void setScheme(String scheme) {
         this.scheme = scheme;
     }
 
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Set the transformer name under which the transformer gets referenced when specifying the input/output data type
+     * on routes. If you specify a transformer name that matches a data type scheme like 'csv' the transformer will be
+     * picked up for all of 'csv:*' from/to Java transformation. Note that the scheme matching is performed only when no
+     * exactly matched transformer exists.
+     *
+     * @param name transformer name
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
     public String getFromType() {
         return fromType;
     }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/TransformersDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/TransformersDefinition.java
index fea9b233691..907fc405db5 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/TransformersDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/TransformersDefinition.java
@@ -37,6 +37,7 @@ public class TransformersDefinition {
     @XmlElements({
             @XmlElement(name = "dataFormatTransformer", type = DataFormatTransformerDefinition.class),
             @XmlElement(name = "endpointTransformer", type = EndpointTransformerDefinition.class),
+            @XmlElement(name = "loadTransformer", type = LoadTransformerDefinition.class),
             @XmlElement(name = "customTransformer", type = CustomTransformerDefinition.class) })
     private List<TransformerDefinition> transformers;
 
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/ContractAdvice.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/ContractAdvice.java
index 7c5954fa24c..22cdc199be5 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/ContractAdvice.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/ContractAdvice.java
@@ -20,6 +20,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.ValidationException;
+import org.apache.camel.processor.transformer.TypeConverterTransformer;
 import org.apache.camel.spi.CamelInternalProcessorAdvice;
 import org.apache.camel.spi.Contract;
 import org.apache.camel.spi.DataType;
@@ -48,7 +49,7 @@ import org.slf4j.LoggerFactory;
 public class ContractAdvice implements CamelInternalProcessorAdvice {
     private static final Logger LOG = LoggerFactory.getLogger(ContractAdvice.class);
 
-    private Contract contract;
+    private final Contract contract;
 
     public ContractAdvice(Contract contract) {
         this.contract = contract;
@@ -117,7 +118,7 @@ public class ContractAdvice implements CamelInternalProcessorAdvice {
 
     private void doTransform(Message message, DataType from, DataType to) throws Exception {
         if (from == null) {
-            // If 'from' is null, only Java-Java convertion is performed.
+            // If 'from' is null, only Java-Java conversion is performed.
             // It means if 'to' is other than Java, it's assumed to be already in expected type.
             convertIfRequired(message, to);
             return;
@@ -127,7 +128,7 @@ public class ContractAdvice implements CamelInternalProcessorAdvice {
         convertIfRequired(message, from);
 
         if (applyMatchedTransformer(message, from, to)) {
-            // Found matched transformer. Java-Java transformer is also allowed.
+            // Found matched transformer. Java->Java transformer is also allowed.
             return;
         } else if (from.isJavaType()) {
             // Try TypeConverter as a fallback for Java->Java transformation
@@ -143,39 +144,35 @@ public class ContractAdvice implements CamelInternalProcessorAdvice {
         throw new IllegalArgumentException("No Transformer found for [from='" + from + "', to='" + to + "']");
     }
 
-    private boolean convertIfRequired(Message message, DataType type) throws Exception {
-        // TODO for better performance it may be better to add TypeConverterTransformer
-        // into transformer registry automatically to avoid unnecessary scan in transformer registry
-        if (type != null && type.isJavaType() && type.getName() != null && message != null && message.getBody() != null) {
-            CamelContext context = message.getExchange().getContext();
-            Class<?> typeJava = getClazz(type.getName(), context);
-            if (!typeJava.isAssignableFrom(message.getBody().getClass())) {
-                LOG.debug("Converting to '{}'", typeJava.getName());
-                message.setBody(message.getMandatoryBody(typeJava));
-                return true;
-            }
+    private void convertIfRequired(Message message, DataType type) throws Exception {
+        if (DataType.isAnyType(type) || !DataType.isJavaType(type) || type.getName() == null) {
+            return;
         }
-        return false;
-    }
 
-    private boolean applyTransformer(Transformer transformer, Message message, DataType from, DataType to) throws Exception {
+        CamelContext context = message.getExchange().getContext();
+        Transformer transformer = context.resolveTransformer(DataType.ANY, type);
         if (transformer != null) {
-            LOG.debug("Applying transformer: from='{}', to='{}', transformer='{}'", from, to, transformer);
-            transformer.transform(message, from, to);
-            return true;
+            transformer.transform(message, DataType.ANY, type);
+        } else {
+            new TypeConverterTransformer(type).transform(message, DataType.ANY, type);
         }
-        return false;
     }
 
     private boolean applyMatchedTransformer(Message message, DataType from, DataType to) throws Exception {
         Transformer transformer = message.getExchange().getContext().resolveTransformer(from, to);
-        return applyTransformer(transformer, message, from, to);
+        if (transformer == null) {
+            return false;
+        }
+
+        LOG.debug("Applying transformer: from='{}', to='{}', transformer='{}'", from, to, transformer);
+        transformer.transform(message, from, to);
+        return true;
     }
 
     private boolean applyTransformerChain(Message message, DataType from, DataType to) throws Exception {
         CamelContext context = message.getExchange().getContext();
-        Transformer fromTransformer = context.resolveTransformer(from.getModel());
-        Transformer toTransformer = context.resolveTransformer(to.getModel());
+        Transformer fromTransformer = context.resolveTransformer(DataType.ANY, from);
+        Transformer toTransformer = context.resolveTransformer(DataType.ANY, to);
         if (fromTransformer != null && toTransformer != null) {
             LOG.debug("Applying transformer 1/2: from='{}', to='{}', transformer='{}'", from, to, fromTransformer);
             fromTransformer.transform(message, from, new DataType(Object.class));
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/AnnotationTransformerLoader.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/AnnotationTransformerLoader.java
new file mode 100644
index 00000000000..77b23515cc8
--- /dev/null
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/AnnotationTransformerLoader.java
@@ -0,0 +1,198 @@
+/*
+ * 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.processor.transformer;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.Message;
+import org.apache.camel.TypeConverterLoaderException;
+import org.apache.camel.impl.engine.DefaultPackageScanClassResolver;
+import org.apache.camel.impl.engine.TransformerKey;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.PackageScanClassResolver;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.TransformerLoader;
+import org.apache.camel.spi.TransformerRegistry;
+import org.apache.camel.support.PluginHelper;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Transformer loader scans packages for {@link org.apache.camel.spi.Transformer} classes annotated with
+ * {@link DataType} annotation.
+ */
+public class AnnotationTransformerLoader extends Transformer implements TransformerLoader, CamelContextAware {
+
+    public static final String META_INF_SERVICES = "META-INF/services/org/apache/camel/Transformer";
+
+    private static final Logger LOG = LoggerFactory.getLogger(AnnotationTransformerLoader.class);
+
+    private CamelContext camelContext;
+
+    private String packageName;
+
+    private PackageScanClassResolver resolver;
+
+    private final Set<Class<?>> visitedClasses = new HashSet<>();
+    private final Set<String> visitedURIs = new HashSet<>();
+
+    @Override
+    public void load(TransformerRegistry registry) {
+        ObjectHelper.notNull(camelContext, "camelContext");
+
+        if (resolver == null) {
+            if (camelContext instanceof ExtendedCamelContext) {
+                resolver = PluginHelper.getPackageScanClassResolver(camelContext);
+            } else {
+                resolver = new DefaultPackageScanClassResolver();
+            }
+        }
+
+        Set<String> packages = new HashSet<>();
+
+        if (packageName == null || packageName.equals("*")) {
+            LOG.trace("Searching for {} services", META_INF_SERVICES);
+            try {
+                ClassLoader ccl = Thread.currentThread().getContextClassLoader();
+                if (ccl != null) {
+                    findPackages(packages, ccl);
+                }
+                findPackages(packages, getClass().getClassLoader());
+                if (packages.isEmpty()) {
+                    LOG.debug("No package names found to be used for classpath scanning for annotated data types.");
+                    return;
+                }
+            } catch (Exception e) {
+                throw new TypeConverterLoaderException(
+                        "Cannot find package names to be used for classpath scanning for annotated data types.", e);
+            }
+        } else {
+            packages.add(packageName);
+        }
+
+        // scan packages and load annotated transformer classes
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Found data type packages to scan: {}", String.join(", ", packages));
+        }
+        Set<Class<?>> scannedClasses = resolver.findAnnotated(DataTypeTransformer.class, packages.toArray(new String[] {}));
+        if (!scannedClasses.isEmpty()) {
+            LOG.debug("Found {} packages with {} @DataType classes to load", packages.size(), scannedClasses.size());
+
+            // load all the found classes into the type data type registry
+            for (Class<?> type : scannedClasses) {
+                if (acceptClass(type)) {
+                    if (LOG.isTraceEnabled()) {
+                        LOG.trace("Loading data type annotation: {}", ObjectHelper.name(type));
+                    }
+                    registerTransformer(registry, type);
+                }
+            }
+        }
+
+        // now clear the maps so we do not hold references
+        visitedClasses.clear();
+        visitedURIs.clear();
+    }
+
+    private void registerTransformer(TransformerRegistry registry, Class<?> type) {
+        if (visitedClasses.contains(type)) {
+            return;
+        }
+        visitedClasses.add(type);
+
+        try {
+            if (Transformer.class.isAssignableFrom(type) && type.isAnnotationPresent(DataTypeTransformer.class)) {
+                DataTypeTransformer dt = type.getAnnotation(DataTypeTransformer.class);
+                Transformer transformer = (Transformer) camelContext.getInjector().newInstance(type);
+                if (!ObjectHelper.isEmpty(dt.name())) {
+                    registry.put(new TransformerKey(dt.name()), transformer);
+                }
+
+                if (!DataType.isAnyType(new DataType(dt.fromType())) || !DataType.isAnyType(new DataType(dt.toType()))) {
+                    registry.put(new TransformerKey(new DataType(dt.fromType()), new DataType(dt.toType())), transformer);
+                }
+            }
+        } catch (NoClassDefFoundError e) {
+            LOG.debug("Ignoring transformer type: {} as a dependent class could not be found: {}",
+                    type.getCanonicalName(), e, e);
+        }
+    }
+
+    protected boolean acceptClass(Class<?> type) {
+        return Transformer.class.isAssignableFrom(type) && type.isAnnotationPresent(DataTypeTransformer.class);
+    }
+
+    protected void findPackages(Set<String> packages, ClassLoader classLoader) throws IOException {
+        Enumeration<URL> resources = classLoader.getResources(META_INF_SERVICES);
+        while (resources.hasMoreElements()) {
+            URL url = resources.nextElement();
+            String path = url.getPath();
+            if (!visitedURIs.contains(path)) {
+                // remember we have visited this uri so we wont read it twice
+                visitedURIs.add(path);
+                LOG.debug("Loading file {} to retrieve list of packages, from url: {}", META_INF_SERVICES, url);
+                try (BufferedReader reader
+                        = IOHelper.buffered(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8))) {
+                    while (true) {
+                        String line = reader.readLine();
+                        if (line == null) {
+                            break;
+                        }
+                        line = line.trim();
+                        if (line.startsWith("#") || line.length() == 0) {
+                            continue;
+                        }
+                        packages.add(line);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void transform(Message message, DataType from, DataType to) throws Exception {
+        // noop
+    }
+
+    public void setPackageName(String packageName) {
+        this.packageName = packageName;
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+}
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TransformReifier.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/ByteArrayDataTypeTransformer.java
similarity index 50%
copy from core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TransformReifier.java
copy to core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/ByteArrayDataTypeTransformer.java
index 4f7c4e1069e..d553d979ea1 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TransformReifier.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/ByteArrayDataTypeTransformer.java
@@ -14,24 +14,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.reifier;
 
-import org.apache.camel.Expression;
-import org.apache.camel.Processor;
-import org.apache.camel.Route;
-import org.apache.camel.model.ProcessorDefinition;
-import org.apache.camel.model.TransformDefinition;
-import org.apache.camel.processor.TransformProcessor;
+package org.apache.camel.processor.transformer;
 
-public class TransformReifier extends ExpressionReifier<TransformDefinition> {
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
 
-    public TransformReifier(Route route, ProcessorDefinition<?> definition) {
-        super(route, (TransformDefinition) definition);
-    }
+/**
+ * Generic binary data type uses Camel message body converter mechanism to convert content to byte array representation.
+ */
+@DataTypeTransformer(name = "application-octet-stream")
+public class ByteArrayDataTypeTransformer extends Transformer {
+
+    private static final Transformer DELEGATE = new TypeConverterTransformer(byte[].class);
 
     @Override
-    public Processor createProcessor() throws Exception {
-        Expression expr = createExpression(definition.getExpression());
-        return new TransformProcessor(expr);
+    public void transform(Message message, DataType from, DataType to) throws Exception {
+        DELEGATE.transform(message, from, to);
+
+        message.setHeader(Exchange.CONTENT_TYPE, "application/octet-stream");
     }
 }
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/DataFormatTransformer.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/DataFormatTransformer.java
index 64afbf8f78a..7e197d7c942 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/DataFormatTransformer.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/DataFormatTransformer.java
@@ -42,6 +42,9 @@ public class DataFormatTransformer extends Transformer {
     private DataFormat dataFormat;
     private String transformerString;
 
+    public DataFormatTransformer() {
+    }
+
     public DataFormatTransformer(CamelContext context) {
         setCamelContext(context);
     }
@@ -59,10 +62,10 @@ public class DataFormatTransformer extends Transformer {
         CamelContext context = exchange.getContext();
 
         // Unmarshaling into Java Object
-        if ((to == null || to.isJavaType()) && (from.equals(getFrom()) || from.getModel().equals(getModel()))) {
+        if ((DataType.isAnyType(to) || to.isJavaType()) && (from.equals(getFrom()) || from.getScheme().equals(getName()))) {
             LOG.debug("Unmarshaling with: {}", dataFormat);
             Object answer = dataFormat.unmarshal(exchange, message.getBody(InputStream.class));
-            if (to != null && to.getName() != null) {
+            if (!DataType.isAnyType(to) && to.getName() != null) {
                 Class<?> toClass = context.getClassResolver().resolveClass(to.getName());
                 if (!toClass.isAssignableFrom(answer.getClass())) {
                     LOG.debug("Converting to: {}", toClass.getName());
@@ -72,9 +75,10 @@ public class DataFormatTransformer extends Transformer {
             message.setBody(answer);
 
             // Marshaling from Java Object
-        } else if ((from == null || from.isJavaType()) && (to.equals(getTo()) || to.getModel().equals(getModel()))) {
+        } else if ((DataType.isAnyType(from) || from.isJavaType())
+                && (to.equals(getTo()) || to.getScheme().equals(getName()))) {
             Object input = message.getBody();
-            if (from != null && from.getName() != null) {
+            if (!DataType.isAnyType(from) && from.getName() != null) {
                 Class<?> fromClass = context.getClassResolver().resolveClass(from.getName());
                 if (!fromClass.isAssignableFrom(input.getClass())) {
                     LOG.debug("Converting to: {}", fromClass.getName());
@@ -105,8 +109,8 @@ public class DataFormatTransformer extends Transformer {
     @Override
     public String toString() {
         if (transformerString == null) {
-            transformerString = String.format("DataFormatTransformer[scheme='%s', from='%s', to='%s', dataFormat='%s']",
-                    getModel(), getFrom(), getTo(), dataFormat);
+            transformerString = String.format("DataFormatTransformer[name='%s', from='%s', to='%s', dataFormat='%s']",
+                    getName(), getFrom(), getTo(), dataFormat);
         }
         return transformerString;
     }
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/DataTypeProcessor.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/DataTypeProcessor.java
new file mode 100644
index 00000000000..a7f9212bead
--- /dev/null
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/DataTypeProcessor.java
@@ -0,0 +1,120 @@
+/*
+ * 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.processor.transformer;
+
+import java.util.Optional;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.impl.engine.TransformerKey;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeAware;
+import org.apache.camel.spi.Transformer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Processor applies data type conversion based on given format name. Searches for matching data type transformer in
+ * context and applies its logic.
+ */
+public class DataTypeProcessor implements Processor {
+
+    public static final String DATA_TYPE_PROPERTY = "CamelDataType";
+
+    private static final Logger LOG = LoggerFactory.getLogger(DataTypeProcessor.class);
+
+    private String fromType;
+    private String toType;
+
+    private boolean ignoreMissingDataType;
+
+    private Transformer transformer;
+
+    public DataTypeProcessor() {
+    }
+
+    public DataTypeProcessor(String fromType, String toType) {
+        this.fromType = fromType;
+        this.toType = toType;
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        if (toType == null && exchange.hasProperties() && exchange.getProperties().containsKey(DATA_TYPE_PROPERTY)) {
+            toType = exchange.getProperty(DATA_TYPE_PROPERTY, String.class);
+        }
+
+        if (toType == null || toType.isEmpty()) {
+            return;
+        }
+
+        Message message = exchange.getMessage();
+
+        DataType toDataType = new DataType(toType);
+        DataType fromDataType = DataType.ANY;
+        if (fromType != null) {
+            fromDataType = new DataType(fromType);
+        } else if (message instanceof DataTypeAware) {
+            fromDataType = ((DataTypeAware) message).getDataType();
+        }
+
+        Optional<Transformer> dataTypeTransformer = doLookupTransformer(exchange.getContext(), fromDataType, toDataType);
+        if (dataTypeTransformer.isPresent()) {
+            dataTypeTransformer.get().transform(message, fromDataType, toDataType);
+        } else if (ignoreMissingDataType) {
+            LOG.debug("Unable to find  data type transformer from {} to type {}", fromDataType, toDataType);
+        } else {
+            throw new CamelExecutionException(
+                    String.format("Missing data type transformer from %s to type %s", fromDataType, toDataType), exchange);
+        }
+    }
+
+    private Optional<Transformer> doLookupTransformer(CamelContext context, DataType fromType, DataType toType) {
+        if (transformer != null) {
+            return Optional.of(transformer);
+        }
+
+        Transformer maybeTransformer
+                = context.getTransformerRegistry().resolveTransformer(new TransformerKey(fromType, toType));
+        if (maybeTransformer != null) {
+            this.transformer = maybeTransformer;
+            return Optional.of(maybeTransformer);
+        }
+
+        return Optional.empty();
+    }
+
+    public void setFromType(String fromType) {
+        this.fromType = fromType;
+    }
+
+    public void setToType(String toType) {
+        this.toType = toType;
+    }
+
+    public void setTransformer(Transformer transformer) {
+        this.transformer = transformer;
+    }
+
+    public void setIgnoreMissingDataType(boolean ignoreMissingDataType) {
+        this.ignoreMissingDataType = ignoreMissingDataType;
+    }
+}
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/DefaultTransformerLoader.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/DefaultTransformerLoader.java
new file mode 100644
index 00000000000..aaf8d6adcf4
--- /dev/null
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/DefaultTransformerLoader.java
@@ -0,0 +1,48 @@
+/*
+ * 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.processor.transformer;
+
+import org.apache.camel.Message;
+import org.apache.camel.impl.engine.TransformerKey;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.TransformerLoader;
+import org.apache.camel.spi.TransformerRegistry;
+
+/**
+ * Transformer loader loads known default {@link Transformer} implementations.
+ */
+public class DefaultTransformerLoader extends Transformer implements TransformerLoader {
+
+    @Override
+    public void load(TransformerRegistry registry) {
+        Transformer[] defaultTransformers = new Transformer[] {
+                new ByteArrayDataTypeTransformer(),
+                new StringDataTypeTransformer()
+        };
+
+        for (Transformer defaultTransformer : defaultTransformers) {
+            registry.put(TransformerKey.createFrom(defaultTransformer), defaultTransformer);
+        }
+    }
+
+    @Override
+    public void transform(Message message, DataType from, DataType to) throws Exception {
+        // noop
+    }
+}
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/ProcessorTransformer.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/ProcessorTransformer.java
index 62455d9422f..e5ab53860e7 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/ProcessorTransformer.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/ProcessorTransformer.java
@@ -40,6 +40,9 @@ public class ProcessorTransformer extends Transformer {
     private Processor processor;
     private String transformerString;
 
+    public ProcessorTransformer() {
+    }
+
     public ProcessorTransformer(CamelContext context) {
         setCamelContext(context);
     }
@@ -101,8 +104,8 @@ public class ProcessorTransformer extends Transformer {
     @Override
     public String toString() {
         if (transformerString == null) {
-            transformerString = String.format("ProcessorTransformer[scheme='%s', from='%s', to='%s', processor='%s']",
-                    getModel(), getFrom(), getTo(), processor);
+            transformerString = String.format("ProcessorTransformer[name='%s', from='%s', to='%s', processor='%s']",
+                    getName(), getFrom(), getTo(), processor);
         }
         return transformerString;
     }
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/StringDataTypeTransformer.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/StringDataTypeTransformer.java
new file mode 100644
index 00000000000..02e53b2a06b
--- /dev/null
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/StringDataTypeTransformer.java
@@ -0,0 +1,46 @@
+/*
+ * 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.processor.transformer;
+
+import java.nio.charset.StandardCharsets;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePropertyKey;
+import org.apache.camel.Message;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
+
+/**
+ * Generic String data type converts Exchange payload to String representation using the Camel message body converter
+ * mechanism. By default, uses UTF-8 charset as encoding.
+ */
+@DataTypeTransformer(name = "text-plain")
+public class StringDataTypeTransformer extends Transformer {
+
+    private static final Transformer DELEGATE = new TypeConverterTransformer(String.class);
+
+    @Override
+    public void transform(Message message, DataType from, DataType to) throws Exception {
+        message.getExchange().setProperty(ExchangePropertyKey.CHARSET_NAME, StandardCharsets.UTF_8.name());
+
+        DELEGATE.transform(message, from, to);
+
+        message.setHeader(Exchange.CONTENT_TYPE, "text/plain");
+    }
+}
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/TypeConverterTransformer.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/TypeConverterTransformer.java
new file mode 100644
index 00000000000..bbd7917a357
--- /dev/null
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/transformer/TypeConverterTransformer.java
@@ -0,0 +1,80 @@
+/*
+ * 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.processor.transformer;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.InvalidPayloadException;
+import org.apache.camel.Message;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Data type converter receives a name and a target type in order to use traditional exchange body conversion mechanisms
+ * in order to transform the message body to a given type.
+ */
+public class TypeConverterTransformer extends Transformer {
+
+    private static final Logger LOG = LoggerFactory.getLogger(TypeConverterTransformer.class);
+
+    private DataType dataType;
+    private Class<?> type;
+
+    public TypeConverterTransformer(DataType type) {
+        super(type.getFullName());
+        this.dataType = type;
+    }
+
+    public TypeConverterTransformer(Class<?> type) {
+        super("java:" + type.getName());
+        this.type = type;
+    }
+
+    @Override
+    public void transform(Message message, DataType from, DataType to) {
+        if (message == null || message.getBody() == null) {
+            return;
+        }
+
+        try {
+            if (dataType != null) {
+                if (DataType.isJavaType(dataType) && dataType.getName() != null) {
+                    CamelContext context = message.getExchange().getContext();
+                    type = context.getClassResolver().resolveMandatoryClass(dataType.getName());
+                }
+            }
+
+            if (type != null && !type.isAssignableFrom(message.getBody().getClass())) {
+                LOG.debug("Converting to '{}'", type.getName());
+                message.setBody(message.getMandatoryBody(type));
+            }
+        } catch (InvalidPayloadException | ClassNotFoundException e) {
+            throw new CamelExecutionException(
+                    String.format("Failed to convert body to '%s' content using type conversion for %s",
+                            getName(), ObjectHelper.name(type)),
+                    message.getExchange(), e);
+        }
+    }
+
+    public Class<?> getType() {
+        return type;
+    }
+}
diff --git a/core/camel-core-processor/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/application-octet-stream b/core/camel-core-processor/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/application-octet-stream
new file mode 100644
index 00000000000..6d209870e44
--- /dev/null
+++ b/core/camel-core-processor/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/application-octet-stream
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.processor.transformer.ByteArrayDataTypeTransformer
diff --git a/core/camel-core-processor/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/plain-text b/core/camel-core-processor/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/plain-text
new file mode 100644
index 00000000000..a2347583375
--- /dev/null
+++ b/core/camel-core-processor/src/main/resources/META-INF/services/org/apache/camel/datatype/transformer/plain-text
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.processor.transformer.StringDataTypeTransformer
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TransformReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TransformReifier.java
index 4f7c4e1069e..a8b7b41c55c 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TransformReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TransformReifier.java
@@ -22,6 +22,7 @@ import org.apache.camel.Route;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.TransformDefinition;
 import org.apache.camel.processor.TransformProcessor;
+import org.apache.camel.processor.transformer.DataTypeProcessor;
 
 public class TransformReifier extends ExpressionReifier<TransformDefinition> {
 
@@ -31,6 +32,15 @@ public class TransformReifier extends ExpressionReifier<TransformDefinition> {
 
     @Override
     public Processor createProcessor() throws Exception {
+        if (definition.getExpression() != null && definition.getToType() != null) {
+            throw new IllegalArgumentException(
+                    "Both expression and data type set on transform EIP - please choose only one of them");
+        }
+
+        if (definition.getToType() != null) {
+            return new DataTypeProcessor(definition.getFromType(), definition.getToType());
+        }
+
         Expression expr = createExpression(definition.getExpression());
         return new TransformProcessor(expr);
     }
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/CustomTransformerReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/CustomTransformerReifier.java
index 26ed5f1839d..7ab18da7177 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/CustomTransformerReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/CustomTransformerReifier.java
@@ -39,7 +39,7 @@ public class CustomTransformerReifier extends TransformerReifier<CustomTransform
             if (transformer == null) {
                 throw new IllegalArgumentException("Cannot find transformer with ref:" + definition.getRef());
             }
-            if (transformer.getModel() != null || transformer.getFrom() != null || transformer.getTo() != null) {
+            if (transformer.getName() != null || transformer.getFrom() != null || transformer.getTo() != null) {
                 throw new IllegalArgumentException(
                         String.format("Transformer '%s' is already in use. Please check if duplicate transformer exists.",
                                 definition.getRef()));
@@ -53,7 +53,8 @@ public class CustomTransformerReifier extends TransformerReifier<CustomTransform
             transformer = camelContext.getInjector().newInstance(transformerClass, false);
         }
         transformer.setCamelContext(camelContext);
-        return transformer.setModel(definition.getScheme()).setFrom(definition.getFromType()).setTo(definition.getToType());
+        return transformer.setName(definition.getScheme(), definition.getName()).setFrom(definition.getFromType())
+                .setTo(definition.getToType());
     }
 
 }
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/DataFormatTransformerReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/DataFormatTransformerReifier.java
index 294a5c5ea29..261f1db553c 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/DataFormatTransformerReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/DataFormatTransformerReifier.java
@@ -34,7 +34,8 @@ public class DataFormatTransformerReifier extends TransformerReifier<DataFormatT
     protected Transformer doCreateTransformer() {
         DataFormat dataFormat
                 = DataFormatReifier.getDataFormat(camelContext, definition.getDataFormatType());
-        return new DataFormatTransformer(camelContext).setDataFormat(dataFormat).setModel(definition.getScheme())
+        return new DataFormatTransformer(camelContext).setDataFormat(dataFormat)
+                .setName(definition.getScheme(), definition.getName())
                 .setFrom(definition.getFromType()).setTo(definition.getToType());
     }
 
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/EndpointTransformerReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/EndpointTransformerReifier.java
index 9877f41eee2..2afdcf20f4a 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/EndpointTransformerReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/EndpointTransformerReifier.java
@@ -38,7 +38,7 @@ public class EndpointTransformerReifier extends TransformerReifier<EndpointTrans
                 : lookupByNameAndType(parseString(definition.getRef()), Endpoint.class);
         SendProcessor processor = new SendProcessor(endpoint, ExchangePattern.InOut);
         return new ProcessorTransformer(camelContext).setProcessor(processor)
-                .setModel(parseString(definition.getScheme()))
+                .setName(parseString(definition.getScheme()), parseString(definition.getName()))
                 .setFrom(parseString(definition.getFromType()))
                 .setTo(parseString(definition.getToType()));
     }
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/DataFormatTransformerReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/LoadTransformerReifier.java
similarity index 53%
copy from core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/DataFormatTransformerReifier.java
copy to core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/LoadTransformerReifier.java
index 294a5c5ea29..14a90802b30 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/DataFormatTransformerReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/LoadTransformerReifier.java
@@ -17,25 +17,28 @@
 package org.apache.camel.reifier.transformer;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.model.transformer.DataFormatTransformerDefinition;
+import org.apache.camel.model.transformer.LoadTransformerDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
-import org.apache.camel.processor.transformer.DataFormatTransformer;
-import org.apache.camel.reifier.dataformat.DataFormatReifier;
-import org.apache.camel.spi.DataFormat;
+import org.apache.camel.processor.transformer.AnnotationTransformerLoader;
+import org.apache.camel.processor.transformer.DefaultTransformerLoader;
 import org.apache.camel.spi.Transformer;
 
-public class DataFormatTransformerReifier extends TransformerReifier<DataFormatTransformerDefinition> {
+public class LoadTransformerReifier extends TransformerReifier<LoadTransformerDefinition> {
 
-    public DataFormatTransformerReifier(CamelContext camelContext, TransformerDefinition definition) {
-        super(camelContext, (DataFormatTransformerDefinition) definition);
+    public LoadTransformerReifier(CamelContext camelContext, TransformerDefinition definition) {
+        super(camelContext, (LoadTransformerDefinition) definition);
     }
 
     @Override
     protected Transformer doCreateTransformer() {
-        DataFormat dataFormat
-                = DataFormatReifier.getDataFormat(camelContext, definition.getDataFormatType());
-        return new DataFormatTransformer(camelContext).setDataFormat(dataFormat).setModel(definition.getScheme())
-                .setFrom(definition.getFromType()).setTo(definition.getToType());
+        if (definition.getDefaults() != null && parseBoolean(definition.getDefaults(), false)) {
+            return new DefaultTransformerLoader();
+        } else {
+            AnnotationTransformerLoader transformerLoader = new AnnotationTransformerLoader();
+            transformerLoader.setCamelContext(camelContext);
+            transformerLoader.setPackageName(definition.getPackageScan());
+            return transformerLoader;
+        }
     }
 
 }
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/TransformerReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/TransformerReifier.java
index 63707ea4eaa..69a61a1ffc3 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/TransformerReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/transformer/TransformerReifier.java
@@ -24,6 +24,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.model.transformer.CustomTransformerDefinition;
 import org.apache.camel.model.transformer.DataFormatTransformerDefinition;
 import org.apache.camel.model.transformer.EndpointTransformerDefinition;
+import org.apache.camel.model.transformer.LoadTransformerDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.reifier.AbstractReifier;
 import org.apache.camel.spi.ReifierStrategy;
@@ -80,6 +81,8 @@ public abstract class TransformerReifier<T> extends AbstractReifier {
             return new DataFormatTransformerReifier(camelContext, definition);
         } else if (definition instanceof EndpointTransformerDefinition) {
             return new EndpointTransformerReifier(camelContext, definition);
+        } else if (definition instanceof LoadTransformerDefinition) {
+            return new LoadTransformerReifier(camelContext, definition);
         }
         return null;
     }
diff --git a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index 92a0d7963ca..fb2662db6b5 100644
--- a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -577,9 +577,15 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
     }
 
     private static ValueHolder<String> createTransformerKey(TransformerDefinition def) {
-        return org.apache.camel.util.ObjectHelper.isNotEmpty(def.getScheme())
-                ? new TransformerKey(def.getScheme())
-                : new TransformerKey(new DataType(def.getFromType()), new DataType(def.getToType()));
+        if (org.apache.camel.util.ObjectHelper.isNotEmpty(def.getScheme())) {
+            return org.apache.camel.util.ObjectHelper.isNotEmpty(def.getName())
+                    ? new TransformerKey(def.getScheme() + ":" + def.getName()) : new TransformerKey(def.getScheme());
+        }
+        if (org.apache.camel.util.ObjectHelper.isNotEmpty(def.getName())) {
+            return new TransformerKey(def.getName());
+        } else {
+            return new TransformerKey(new DataType(def.getFromType()), new DataType(def.getToType()));
+        }
     }
 
     private void initValidators() {
diff --git a/core/camel-core/src/test/java/org/apache/camel/builder/TransformerBuilderTest.java b/core/camel-core/src/test/java/org/apache/camel/builder/TransformerBuilderTest.java
index 38e34f17476..338d32dbfe2 100644
--- a/core/camel-core/src/test/java/org/apache/camel/builder/TransformerBuilderTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/builder/TransformerBuilderTest.java
@@ -63,7 +63,7 @@ public class TransformerBuilderTest extends TestSupport {
         RouteBuilder builder = new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                transformer().scheme("other").withJava(MyTransformer.class);
+                transformer().name("other").withJava(MyTransformer.class);
                 from("direct:input").log("test");
             }
         };
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/engine/DefaultTransformerRegistryTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/engine/DefaultTransformerRegistryTest.java
new file mode 100644
index 00000000000..a7de0a24a40
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/engine/DefaultTransformerRegistryTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.impl.engine;
+
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.processor.transformer.ByteArrayDataTypeTransformer;
+import org.apache.camel.processor.transformer.StringDataTypeTransformer;
+import org.apache.camel.spi.Transformer;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class DefaultTransformerRegistryTest {
+
+    private final DefaultTransformerRegistry dataTypeRegistry = new DefaultTransformerRegistry(new DefaultCamelContext());
+
+    @Test
+    public void shouldLookupDefaultDataTypeConverters() throws Exception {
+        Transformer transformer = dataTypeRegistry.resolveTransformer(new TransformerKey("plain-text"));
+        Assertions.assertNotNull(transformer);
+        Assertions.assertEquals(StringDataTypeTransformer.class, transformer.getClass());
+        transformer = dataTypeRegistry.resolveTransformer(new TransformerKey("application-octet-stream"));
+        Assertions.assertNotNull(transformer);
+        Assertions.assertEquals(ByteArrayDataTypeTransformer.class, transformer.getClass());
+        transformer = dataTypeRegistry.resolveTransformer(new TransformerKey("lowercase"));
+        Assertions.assertNotNull(transformer);
+        Assertions.assertEquals(LowercaseDataTypeTransformer.class, transformer.getClass());
+        transformer = dataTypeRegistry.resolveTransformer(new TransformerKey("uppercase"));
+        Assertions.assertNotNull(transformer);
+        Assertions.assertEquals(UppercaseDataTypeTransformer.class, transformer.getClass());
+    }
+
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/engine/DefaultTransformerResolverTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/engine/DefaultTransformerResolverTest.java
new file mode 100644
index 00000000000..b7b17d9d354
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/engine/DefaultTransformerResolverTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.impl.engine;
+
+import org.apache.camel.Message;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.processor.transformer.StringDataTypeTransformer;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class DefaultTransformerResolverTest {
+
+    private DefaultCamelContext camelContext;
+
+    private final DefaultTransformerResolver resolver = new DefaultTransformerResolver();
+
+    @BeforeEach
+    void setup() {
+        this.camelContext = new DefaultCamelContext();
+    }
+
+    @Test
+    public void shouldHandleUnresolvableDataTypeTransformers() throws Exception {
+        Transformer transformer = resolver.resolve(new TransformerKey("unknown"), camelContext);
+        Assertions.assertNull(transformer);
+
+        transformer = resolver.resolve(new TransformerKey(
+                new DataType("foo:fromType"),
+                new DataType("foo:toType")), camelContext);
+        Assertions.assertNull(transformer);
+    }
+
+    @Test
+    public void shouldResolveDataTypeTransformers() throws Exception {
+        Transformer transformer = resolver.resolve(new TransformerKey("plain-text"), camelContext);
+        Assertions.assertNotNull(transformer);
+        Assertions.assertEquals(StringDataTypeTransformer.class, transformer.getClass());
+
+        transformer = resolver.resolve(new TransformerKey("lowercase"), camelContext);
+        Assertions.assertNotNull(transformer);
+        Assertions.assertEquals(LowercaseDataTypeTransformer.class, transformer.getClass());
+
+        transformer = resolver.resolve(new TransformerKey(new DataType("foo"), new DataType("json")), camelContext);
+        Assertions.assertNotNull(transformer);
+        Assertions.assertEquals(FooDataTypeTransformer.class, transformer.getClass());
+    }
+
+    @DataTypeTransformer(name = "foo-json", fromType = "foo", toType = "json")
+    public static class FooDataTypeTransformer extends Transformer {
+
+        @Override
+        public void transform(Message message, DataType fromType, DataType toType) {
+            message.setBody("Foo");
+        }
+    }
+}
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java b/core/camel-core/src/test/java/org/apache/camel/impl/engine/LowercaseDataTypeTransformer.java
similarity index 63%
copy from core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
copy to core/camel-core/src/test/java/org/apache/camel/impl/engine/LowercaseDataTypeTransformer.java
index 23827554acc..3cdf31ee232 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/engine/LowercaseDataTypeTransformer.java
@@ -14,16 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.api.management.mbean;
 
-import org.apache.camel.api.management.ManagedAttribute;
+package org.apache.camel.impl.engine;
 
-public interface ManagedTransformMBean extends ManagedProcessorMBean {
+import org.apache.camel.Message;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
 
-    @ManagedAttribute(description = "The language for the expression")
-    String getExpressionLanguage();
-
-    @ManagedAttribute(description = "Expression to return the transformed message body (the new message body to use)")
-    String getExpression();
+@DataTypeTransformer(name = "lowercase")
+public class LowercaseDataTypeTransformer extends Transformer {
 
+    @Override
+    public void transform(Message message, DataType fromType, DataType toType) {
+        message.setBody(message.getBody(String.class).toLowerCase());
+    }
 }
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java b/core/camel-core/src/test/java/org/apache/camel/impl/engine/UppercaseDataTypeTransformer.java
similarity index 63%
copy from core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
copy to core/camel-core/src/test/java/org/apache/camel/impl/engine/UppercaseDataTypeTransformer.java
index 23827554acc..58cdd93eca7 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/engine/UppercaseDataTypeTransformer.java
@@ -14,16 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.api.management.mbean;
 
-import org.apache.camel.api.management.ManagedAttribute;
+package org.apache.camel.impl.engine;
 
-public interface ManagedTransformMBean extends ManagedProcessorMBean {
+import org.apache.camel.Message;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
 
-    @ManagedAttribute(description = "The language for the expression")
-    String getExpressionLanguage();
-
-    @ManagedAttribute(description = "Expression to return the transformed message body (the new message body to use)")
-    String getExpression();
+@DataTypeTransformer(name = "uppercase")
+public class UppercaseDataTypeTransformer extends Transformer {
 
+    @Override
+    public void transform(Message message, DataType fromType, DataType toType) {
+        message.setBody(message.getBody(String.class).toUpperCase());
+    }
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/TransformDataTypeProcessorTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/TransformDataTypeProcessorTest.java
new file mode 100644
index 00000000000..02ad6bec7ac
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/TransformDataTypeProcessorTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.processor;
+
+import org.apache.camel.Message;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Transformer;
+
+public class TransformDataTypeProcessorTest extends TransformViaDSLTest {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                transformer().name("myDataType").withJava(MyDataTypeTransformer.class);
+                // START SNIPPET: example
+                from("direct:start").transform(new DataType("myDataType")).to("mock:result");
+                // END SNIPPET: example
+            }
+        };
+    }
+
+    public static class MyDataTypeTransformer extends Transformer {
+
+        @Override
+        public void transform(Message message, DataType from, DataType to) throws Exception {
+            message.setBody(message.getBody(String.class) + " World!");
+        }
+    }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/transformer/ByteArrayDataTypeTransformerTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/ByteArrayDataTypeTransformerTest.java
new file mode 100644
index 00000000000..1f5f3011f24
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/ByteArrayDataTypeTransformerTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.processor.transformer;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.engine.DefaultTransformerRegistry;
+import org.apache.camel.impl.engine.TransformerKey;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.support.DefaultExchange;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ByteArrayDataTypeTransformerTest {
+
+    private final DefaultCamelContext camelContext = new DefaultCamelContext();
+
+    private final ByteArrayDataTypeTransformer transformer = new ByteArrayDataTypeTransformer();
+
+    @Test
+    void shouldRetainBytesModel() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setHeader("file", "test.txt");
+        exchange.getMessage().setBody("Test".getBytes(StandardCharsets.UTF_8));
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        Assertions.assertTrue(exchange.getMessage().hasHeaders());
+        assertBinaryBody(exchange, "test.txt", "Test");
+    }
+
+    @Test
+    void shouldTransformFromStringToBytesModel() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setHeader("file", "test1.txt");
+        exchange.getMessage().setBody("Test1");
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        Assertions.assertTrue(exchange.getMessage().hasHeaders());
+        assertBinaryBody(exchange, "test1.txt", "Test1");
+    }
+
+    @Test
+    void shouldTransformFromBytesToBytesModel() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setHeader("file", "test2.txt");
+        exchange.getMessage().setBody("Test2".getBytes(StandardCharsets.UTF_8));
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        Assertions.assertTrue(exchange.getMessage().hasHeaders());
+        assertBinaryBody(exchange, "test2.txt", "Test2");
+    }
+
+    @Test
+    void shouldTransformFromInputStreamToBytesModel() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setHeader("file", "test3.txt");
+        exchange.getMessage().setBody(new ByteArrayInputStream("Test3".getBytes(StandardCharsets.UTF_8)));
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        Assertions.assertTrue(exchange.getMessage().hasHeaders());
+        assertBinaryBody(exchange, "test3.txt", "Test3");
+    }
+
+    @Test
+    public void shouldResolveTransformer() throws Exception {
+        DefaultTransformerRegistry transformerRegistry = new DefaultTransformerRegistry(camelContext);
+        Transformer transformer = transformerRegistry.resolveTransformer(new TransformerKey("application-octet-stream"));
+        Assertions.assertNotNull(transformer);
+    }
+
+    private static void assertBinaryBody(Exchange exchange, String key, String content) {
+        assertEquals(key, exchange.getMessage().getHeader("file"));
+
+        assertEquals(byte[].class, exchange.getMessage().getBody().getClass());
+        assertEquals(content, exchange.getMessage().getBody(String.class));
+    }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/transformer/DataTypeProcessorTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/DataTypeProcessorTest.java
new file mode 100644
index 00000000000..065e148f088
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/DataTypeProcessorTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.processor.transformer;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Exchange;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.support.DefaultExchange;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class DataTypeProcessorTest {
+
+    private final DefaultCamelContext camelContext = new DefaultCamelContext();
+
+    private final DataTypeProcessor processor = new DataTypeProcessor();
+
+    @BeforeEach
+    void setup() {
+        CamelContextAware.trySetCamelContext(processor, camelContext);
+    }
+
+    @Test
+    public void shouldApplyDataTypeConverterFromAnnotationLookup() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setBody(new ByteArrayInputStream("Test".getBytes(StandardCharsets.UTF_8)));
+        processor.setToType("uppercase");
+        processor.process(exchange);
+
+        assertEquals(String.class, exchange.getMessage().getBody().getClass());
+        assertEquals("TEST", exchange.getMessage().getBody());
+    }
+
+    @Test
+    public void shouldApplyDataTypeConverterFromResourceLookup() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setBody(new ByteArrayInputStream("Test".getBytes(StandardCharsets.UTF_8)));
+        processor.setToType("lowercase");
+        processor.process(exchange);
+
+        assertEquals(String.class, exchange.getMessage().getBody().getClass());
+        assertEquals("test", exchange.getMessage().getBody());
+    }
+
+    @Test
+    public void shouldIgnoreUnknownDataType() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setBody(new ByteArrayInputStream("Test".getBytes(StandardCharsets.UTF_8)));
+        processor.setIgnoreMissingDataType(true);
+        processor.setToType("foo:unknown");
+        processor.process(exchange);
+
+        assertEquals(ByteArrayInputStream.class, exchange.getMessage().getBody().getClass());
+        assertEquals("Test", exchange.getMessage().getBody(String.class));
+    }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/transformer/StringDataTypeTransformerTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/StringDataTypeTransformerTest.java
new file mode 100644
index 00000000000..25b70416c06
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/StringDataTypeTransformerTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.processor.transformer;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.engine.DefaultTransformerRegistry;
+import org.apache.camel.impl.engine.TransformerKey;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.support.DefaultExchange;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class StringDataTypeTransformerTest {
+
+    private final DefaultCamelContext camelContext = new DefaultCamelContext();
+
+    private final StringDataTypeTransformer transformer = new StringDataTypeTransformer();
+
+    @Test
+    void shouldRetainStringModel() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setHeader("file", "test.txt");
+        exchange.getMessage().setBody("Test");
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        Assertions.assertTrue(exchange.getMessage().hasHeaders());
+        assertStringBody(exchange, "test.txt", "Test");
+    }
+
+    @Test
+    void shouldMapFromBinaryToStringModel() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setHeader("file", "test1.txt");
+        exchange.getMessage().setBody("Test1".getBytes(StandardCharsets.UTF_8));
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        Assertions.assertTrue(exchange.getMessage().hasHeaders());
+        assertStringBody(exchange, "test1.txt", "Test1");
+    }
+
+    @Test
+    void shouldMapFromInputStreamToStringModel() throws Exception {
+        Exchange exchange = new DefaultExchange(camelContext);
+
+        exchange.getMessage().setHeader("file", "test3.txt");
+        exchange.getMessage().setBody(new ByteArrayInputStream("Test3".getBytes(StandardCharsets.UTF_8)));
+        transformer.transform(exchange.getMessage(), DataType.ANY, DataType.ANY);
+
+        Assertions.assertTrue(exchange.getMessage().hasHeaders());
+        assertStringBody(exchange, "test3.txt", "Test3");
+    }
+
+    @Test
+    public void shouldLookupDataType() throws Exception {
+        DefaultTransformerRegistry dataTypeRegistry = new DefaultTransformerRegistry(camelContext);
+        Transformer transformer = dataTypeRegistry.resolveTransformer(new TransformerKey("plain-text"));
+        Assertions.assertNotNull(transformer);
+    }
+
+    private static void assertStringBody(Exchange exchange, String key, String content) {
+        assertEquals(key, exchange.getMessage().getHeader("file"));
+
+        assertEquals(String.class, exchange.getMessage().getBody().getClass());
+        assertEquals(content, exchange.getMessage().getBody(String.class));
+    }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/transformer/TransformerRouteTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/TransformerRouteTest.java
index 8a3f850300d..1fdf129e747 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/transformer/TransformerRouteTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/TransformerRouteTest.java
@@ -64,7 +64,7 @@ public class TransformerRouteTest extends ContextTestSupport {
         abcresult.whenAnyExchangeReceived(new Processor() {
             @Override
             public void process(Exchange exchange) throws Exception {
-                LOG.info("Asserting String -> XOrderResponse convertion");
+                LOG.info("Asserting String -> XOrderResponse conversion");
                 assertEquals(XOrderResponse.class, exchange.getIn().getBody().getClass());
             }
 
@@ -75,7 +75,7 @@ public class TransformerRouteTest extends ContextTestSupport {
         xyzresult.whenAnyExchangeReceived(new Processor() {
             @Override
             public void process(Exchange exchange) throws Exception {
-                LOG.info("Asserting String -> XOrderResponse convertion is not yet performed");
+                LOG.info("Asserting String -> XOrderResponse conversion is not yet performed");
                 assertEquals("response", exchange.getIn().getBody());
             }
         });
@@ -97,7 +97,7 @@ public class TransformerRouteTest extends ContextTestSupport {
         xyzresult.whenAnyExchangeReceived(new Processor() {
             @Override
             public void process(Exchange exchange) throws Exception {
-                LOG.info("Asserting String -> XOrderResponse convertion is not yet performed");
+                LOG.info("Asserting String -> XOrderResponse conversion is not yet performed");
                 assertEquals("response", exchange.getIn().getBody());
             }
         });
@@ -119,7 +119,7 @@ public class TransformerRouteTest extends ContextTestSupport {
         xyzresult.whenAnyExchangeReceived(new Processor() {
             @Override
             public void process(Exchange exchange) throws Exception {
-                LOG.info("Asserting String -> XOrderResponse convertion is not yet performed");
+                LOG.info("Asserting String -> XOrderResponse conversion is not yet performed");
                 assertEquals("response", exchange.getIn().getBody());
             }
         });
@@ -141,7 +141,7 @@ public class TransformerRouteTest extends ContextTestSupport {
         xyzresult.whenAnyExchangeReceived(new Processor() {
             @Override
             public void process(Exchange exchange) throws Exception {
-                LOG.info("Asserting String -> XOrderResponse convertion is not yet performed");
+                LOG.info("Asserting String -> XOrderResponse conversion is not yet performed");
                 assertEquals("response", exchange.getIn().getBody());
             }
         });
@@ -178,14 +178,14 @@ public class TransformerRouteTest extends ContextTestSupport {
                 context.getTypeConverterRegistry().addTypeConverters(new MyTypeConverters());
                 from("direct:abc").inputType(AOrder.class).outputType(AOrderResponse.class).process(new Processor() {
                     public void process(Exchange exchange) throws Exception {
-                        LOG.info("Asserting input -> AOrder convertion");
+                        LOG.info("Asserting input -> AOrder conversion");
                         assertEquals(AOrder.class, exchange.getIn().getBody().getClass());
                     }
                 }).to(ExchangePattern.InOut, "direct:xyz").to("mock:abcresult");
 
                 from("direct:xyz").inputType(XOrder.class).outputType(XOrderResponse.class).process(new Processor() {
                     public void process(Exchange exchange) throws Exception {
-                        LOG.info("Asserting input -> XOrder convertion");
+                        LOG.info("Asserting input -> XOrder conversion");
                         assertEquals(XOrder.class, exchange.getIn().getBody().getClass());
                         exchange.getIn().setBody("response");
                     }
@@ -206,12 +206,15 @@ public class TransformerRouteTest extends ContextTestSupport {
                         .withJava(XOrderResponseToOtherTransformer.class);
                 from("direct:custom").inputType("other:OtherXOrder").outputType("other:OtherXOrderResponse")
                         .to(ExchangePattern.InOut, "direct:xyz");
-                transformer().scheme("myDataType").withDataFormat(new MyDataFormatDefinition());
+                transformer().name("myDataType").withDataFormat(new MyDataFormatDefinition());
                 from("direct:testDataType").inputTypeWithValidate("myDataType")
                         .to("direct:testDataTypeStep2");
                 from("direct:testDataTypeStep2").inputType(MyDataType.class)
                         .to("mock:testDataType");
                 validator().type("myDataType").withExpression(bodyAs(String.class).contains("fake"));
+
+                transformer().withDefaults();
+                transformer().scan("com.apache.camel.processor.transformer.custom");
             }
         };
     }
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/custom/CustomDataTypeTransformer.java
similarity index 63%
copy from core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
copy to core/camel-core/src/test/java/org/apache/camel/processor/transformer/custom/CustomDataTypeTransformer.java
index 23827554acc..3dc9339c69e 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/custom/CustomDataTypeTransformer.java
@@ -14,16 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.api.management.mbean;
 
-import org.apache.camel.api.management.ManagedAttribute;
+package org.apache.camel.processor.transformer.custom;
 
-public interface ManagedTransformMBean extends ManagedProcessorMBean {
+import org.apache.camel.Message;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.DataTypeTransformer;
+import org.apache.camel.spi.Transformer;
 
-    @ManagedAttribute(description = "The language for the expression")
-    String getExpressionLanguage();
-
-    @ManagedAttribute(description = "Expression to return the transformed message body (the new message body to use)")
-    String getExpression();
+@DataTypeTransformer(name = "custom")
+public class CustomDataTypeTransformer extends Transformer {
 
+    @Override
+    public void transform(Message message, DataType from, DataType to) throws Exception {
+        message.setBody("customized");
+    }
 }
diff --git a/core/camel-core/src/test/resources/META-INF/services/org/apache/camel/datatype/transformer/foo-json b/core/camel-core/src/test/resources/META-INF/services/org/apache/camel/datatype/transformer/foo-json
new file mode 100644
index 00000000000..9b2546f6062
--- /dev/null
+++ b/core/camel-core/src/test/resources/META-INF/services/org/apache/camel/datatype/transformer/foo-json
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.impl.engine.DefaultTransformerResolverTest$FooDataTypeTransformer
diff --git a/core/camel-core/src/test/resources/META-INF/services/org/apache/camel/datatype/transformer/lowercase b/core/camel-core/src/test/resources/META-INF/services/org/apache/camel/datatype/transformer/lowercase
new file mode 100644
index 00000000000..0ee439ca63b
--- /dev/null
+++ b/core/camel-core/src/test/resources/META-INF/services/org/apache/camel/datatype/transformer/lowercase
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.impl.engine.LowercaseDataTypeTransformer
diff --git a/core/camel-core/src/test/resources/META-INF/services/org/apache/camel/datatype/transformer/uppercase b/core/camel-core/src/test/resources/META-INF/services/org/apache/camel/datatype/transformer/uppercase
new file mode 100644
index 00000000000..734ff7f25ed
--- /dev/null
+++ b/core/camel-core/src/test/resources/META-INF/services/org/apache/camel/datatype/transformer/uppercase
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.impl.engine.UppercaseDataTypeTransformer
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/CamelOpenMBeanTypes.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/CamelOpenMBeanTypes.java
index 991a0325d6f..93b01ebd60d 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/CamelOpenMBeanTypes.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/CamelOpenMBeanTypes.java
@@ -217,14 +217,14 @@ public final class CamelOpenMBeanTypes {
     public static TabularType listTransformersTabularType() throws OpenDataException {
         CompositeType ct = listTransformersCompositeType();
         return new TabularType(
-                "listTransformers", "Lists all the transformers in the registry", ct, new String[] { "scheme", "from", "to" });
+                "listTransformers", "Lists all the transformers in the registry", ct, new String[] { "name", "from", "to" });
     }
 
     public static CompositeType listTransformersCompositeType() throws OpenDataException {
         return new CompositeType(
                 "transformers", "Transformers",
-                new String[] { "scheme", "from", "to", "static", "dynamic", "description" },
-                new String[] { "Scheme", "From", "To", "Static", "Dynamic", "Description" },
+                new String[] { "name", "from", "to", "static", "dynamic", "description" },
+                new String[] { "Name", "From", "To", "Static", "Dynamic", "Description" },
                 new OpenType[] {
                         SimpleType.STRING, SimpleType.STRING, SimpleType.STRING,
                         SimpleType.BOOLEAN, SimpleType.BOOLEAN, SimpleType.STRING });
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
index 23827554acc..271319f9203 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedTransformMBean.java
@@ -26,4 +26,10 @@ public interface ManagedTransformMBean extends ManagedProcessorMBean {
     @ManagedAttribute(description = "Expression to return the transformed message body (the new message body to use)")
     String getExpression();
 
+    @ManagedAttribute(description = "Data type used as defined input for the message transformation")
+    String getFromType();
+
+    @ManagedAttribute(description = "Data type representing the defined outcome of a data type transformation (the new message body to use)")
+    String getToType();
+
 }
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectStrategy.java b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectStrategy.java
index 2338ad1bc89..773573228aa 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectStrategy.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectStrategy.java
@@ -179,6 +179,7 @@ import org.apache.camel.processor.loadbalancer.RoundRobinLoadBalancer;
 import org.apache.camel.processor.loadbalancer.StickyLoadBalancer;
 import org.apache.camel.processor.loadbalancer.TopicLoadBalancer;
 import org.apache.camel.processor.loadbalancer.WeightedLoadBalancer;
+import org.apache.camel.processor.transformer.DataTypeProcessor;
 import org.apache.camel.spi.BrowsableEndpoint;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.spi.ErrorHandler;
@@ -437,7 +438,9 @@ public class DefaultManagementObjectStrategy implements ManagementObjectStrategy
             } else if (target instanceof ThrowExceptionProcessor) {
                 answer = new ManagedThrowException(context, (ThrowExceptionProcessor) target, definition);
             } else if (target instanceof TransformProcessor) {
-                answer = new ManagedTransformer(context, (TransformProcessor) target, (TransformDefinition) definition);
+                answer = new ManagedTransformer(context, target, (TransformDefinition) definition);
+            } else if (target instanceof DataTypeProcessor) {
+                answer = new ManagedTransformer(context, target, (TransformDefinition) definition);
             } else if (target instanceof PredicateValidatingProcessor) {
                 answer = new ManagedValidate(context, (PredicateValidatingProcessor) target, (ValidateDefinition) definition);
             } else if (target instanceof WireTapProcessor) {
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTransformer.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTransformer.java
index 465387af416..00916eb866e 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTransformer.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTransformer.java
@@ -17,18 +17,16 @@
 package org.apache.camel.management.mbean;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.Processor;
 import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.api.management.mbean.ManagedTransformMBean;
 import org.apache.camel.model.TransformDefinition;
-import org.apache.camel.processor.TransformProcessor;
 
 @ManagedResource(description = "Managed Transformer")
 public class ManagedTransformer extends ManagedProcessor implements ManagedTransformMBean {
-    private final TransformProcessor processor;
 
-    public ManagedTransformer(CamelContext context, TransformProcessor processor, TransformDefinition definition) {
+    public ManagedTransformer(CamelContext context, Processor processor, TransformDefinition definition) {
         super(context, processor, definition);
-        this.processor = processor;
     }
 
     @Override
@@ -45,4 +43,14 @@ public class ManagedTransformer extends ManagedProcessor implements ManagedTrans
     public String getExpression() {
         return getDefinition().getExpression().getExpression();
     }
+
+    @Override
+    public String getFromType() {
+        return getDefinition().getFromType();
+    }
+
+    @Override
+    public String getToType() {
+        return getDefinition().getToType();
+    }
 }
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTransformerRegistry.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTransformerRegistry.java
index 8f9943f065f..79ac1ff8c3d 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTransformerRegistry.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedTransformerRegistry.java
@@ -84,18 +84,18 @@ public class ManagedTransformerRegistry extends ManagedService implements Manage
             Collection<Transformer> transformers = transformerRegistry.values();
             for (Transformer transformer : transformers) {
                 CompositeType ct = CamelOpenMBeanTypes.listTransformersCompositeType();
-                String scheme = transformer.getModel();
+                String name = transformer.getName();
                 DataType from = transformer.getFrom();
                 DataType to = transformer.getTo();
                 String desc = transformer.toString();
                 boolean fromStatic
-                        = scheme != null ? transformerRegistry.isStatic(scheme) : transformerRegistry.isStatic(from, to);
+                        = name != null ? transformerRegistry.isStatic(name) : transformerRegistry.isStatic(from, to);
                 boolean fromDynamic
-                        = scheme != null ? transformerRegistry.isDynamic(scheme) : transformerRegistry.isDynamic(from, to);
+                        = name != null ? transformerRegistry.isDynamic(name) : transformerRegistry.isDynamic(from, to);
 
                 CompositeData data = new CompositeDataSupport(
-                        ct, new String[] { "scheme", "from", "to", "static", "dynamic", "description" },
-                        new Object[] { scheme, from.toString(), to.toString(), fromStatic, fromDynamic, desc });
+                        ct, new String[] { "name", "from", "to", "static", "dynamic", "description" },
+                        new Object[] { name, from.toString(), to.toString(), fromStatic, fromDynamic, desc });
                 answer.put(data);
             }
             return answer;
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java
index 104bfdffe68..6d5f01dee05 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java
@@ -85,25 +85,25 @@ public class ManagedTransformerRegistryTest extends ManagementTestSupport {
         TabularData data = (TabularData) mbeanServer.invoke(on, "listTransformers", null, null);
         for (Object row : data.values()) {
             CompositeData composite = (CompositeData) row;
-            String scheme = (String) composite.get("scheme");
+            String name = (String) composite.get("name");
             String from = (String) composite.get("from");
             String to = (String) composite.get("to");
             String description = (String) composite.get("description");
             boolean isStatic = (boolean) composite.get("static");
             boolean isDynamic = (boolean) composite.get("dynamic");
-            LOG.info("[{}][{}][{}][{}][{}][{}]", scheme, from, to, isStatic, isDynamic, description);
+            LOG.info("[{}][{}][{}][{}][{}][{}]", name, from, to, isStatic, isDynamic, description);
             if (description.startsWith("ProcessorTransformer")) {
-                assertEquals(null, scheme);
+                assertEquals(null, name);
                 assertEquals("xml:foo", from);
                 assertEquals("json:bar", to);
             } else if (description.startsWith("DataFormatTransformer")) {
-                assertEquals(null, scheme);
+                assertEquals(null, name);
                 assertEquals("java:" + ManagedTransformerRegistryTest.class.getName(), from);
                 assertEquals("xml:test", to);
             } else if (description.startsWith("MyTransformer")) {
-                assertEquals("custom", scheme);
-                assertEquals(null, from);
-                assertEquals(null, to);
+                assertEquals("custom", name);
+                assertEquals("camel:any", from);
+                assertEquals("camel:any", to);
             } else {
                 fail("Unexpected transformer:" + description);
             }
@@ -121,7 +121,7 @@ public class ManagedTransformerRegistryTest extends ManagementTestSupport {
                         .toType("json:bar")
                         .withUri("direct:transformer");
                 transformer()
-                        .scheme("custom")
+                        .name("custom")
                         .withJava(MyTransformer.class);
 
                 from("direct:start").to("mock:result");
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index 3acd8f38740..1438223c20f 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -1513,8 +1513,14 @@ public class ModelParser extends BaseParser {
         }, outputDefinitionElementHandler(), noValueHandler());
     }
     protected TransformDefinition doParseTransformDefinition() throws IOException, XmlPullParserException {
-        return doParse(new TransformDefinition(),
-            processorDefinitionAttributeHandler(), expressionNodeElementHandler(), noValueHandler());
+        return doParse(new TransformDefinition(), (def, key, val) -> {
+            switch (key) {
+                case "fromType": def.setFromType(val); break;
+                case "toType": def.setToType(val); break;
+                default: return processorDefinitionAttributeHandler().accept(def, key, val);
+            }
+            return true;
+        }, expressionNodeElementHandler(), noValueHandler());
     }
     protected TryDefinition doParseTryDefinition() throws IOException, XmlPullParserException {
         return doParse(new TryDefinition(),
@@ -3242,6 +3248,7 @@ public class ModelParser extends BaseParser {
         return (def, key, val) -> {
             switch (key) {
                 case "fromType": def.setFromType(val); break;
+                case "name": def.setName(val); break;
                 case "scheme": def.setScheme(val); break;
                 case "toType": def.setToType(val); break;
                 default: return false;
@@ -3270,12 +3277,23 @@ public class ModelParser extends BaseParser {
             return true;
         }, noElementHandler(), noValueHandler());
     }
+    protected LoadTransformerDefinition doParseLoadTransformerDefinition() throws IOException, XmlPullParserException {
+        return doParse(new LoadTransformerDefinition(), (def, key, val) -> {
+            switch (key) {
+                case "defaults": def.setDefaults(val); break;
+                case "packageScan": def.setPackageScan(val); break;
+                default: return transformerDefinitionAttributeHandler().accept(def, key, val);
+            }
+            return true;
+        }, noElementHandler(), noValueHandler());
+    }
     protected TransformersDefinition doParseTransformersDefinition() throws IOException, XmlPullParserException {
         return doParse(new TransformersDefinition(),
             noAttributeHandler(), (def, key) -> {
             switch (key) {
                 case "dataFormatTransformer": doAdd(doParseDataFormatTransformerDefinition(), def.getTransformers(), def::setTransformers); break;
                 case "endpointTransformer": doAdd(doParseEndpointTransformerDefinition(), def.getTransformers(), def::setTransformers); break;
+                case "loadTransformer": doAdd(doParseLoadTransformerDefinition(), def.getTransformers(), def::setTransformers); break;
                 case "customTransformer": doAdd(doParseCustomTransformerDefinition(), def.getTransformers(), def::setTransformers); break;
                 default: return false;
             }
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
index 2104066297c..ea0520d9d52 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
+++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
@@ -2381,6 +2381,8 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
+        doWriteAttribute("toType", def.getToType());
+        doWriteAttribute("fromType", def.getFromType());
         doWriteExpressionNodeElements(def);
         endElement(name);
     }
@@ -4547,12 +4549,23 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("uri", def.getUri());
         endElement(name);
     }
+    protected void doWriteLoadTransformerDefinition(
+            String name,
+            LoadTransformerDefinition def)
+            throws IOException {
+        startElement(name);
+        doWriteTransformerDefinitionAttributes(def);
+        doWriteAttribute("defaults", def.getDefaults());
+        doWriteAttribute("packageScan", def.getPackageScan());
+        endElement(name);
+    }
     protected void doWriteTransformerDefinitionAttributes(
             TransformerDefinition def)
             throws IOException {
         doWriteAttribute("toType", def.getToType());
         doWriteAttribute("fromType", def.getFromType());
         doWriteAttribute("scheme", def.getScheme());
+        doWriteAttribute("name", def.getName());
     }
     protected void doWriteTransformerDefinition(
             String name,
@@ -4571,6 +4584,7 @@ public class ModelWriter extends BaseWriter {
             switch (v.getClass().getSimpleName()) {
                 case "DataFormatTransformerDefinition" -> doWriteDataFormatTransformerDefinition("dataFormatTransformer", (DataFormatTransformerDefinition) v);
                 case "EndpointTransformerDefinition" -> doWriteEndpointTransformerDefinition("endpointTransformer", (EndpointTransformerDefinition) v);
+                case "LoadTransformerDefinition" -> doWriteLoadTransformerDefinition("loadTransformer", (LoadTransformerDefinition) v);
                 case "CustomTransformerDefinition" -> doWriteCustomTransformerDefinition("customTransformer", (CustomTransformerDefinition) v);
             }
         });
diff --git a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
index 9b00f8064dc..b0d62b775d7 100644
--- a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
+++ b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
@@ -2381,6 +2381,8 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
+        doWriteAttribute("toType", def.getToType());
+        doWriteAttribute("fromType", def.getFromType());
         doWriteExpressionNodeElements(def);
         endElement(name);
     }
@@ -4547,12 +4549,23 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("uri", def.getUri());
         endElement(name);
     }
+    protected void doWriteLoadTransformerDefinition(
+            String name,
+            LoadTransformerDefinition def)
+            throws IOException {
+        startElement(name);
+        doWriteTransformerDefinitionAttributes(def);
+        doWriteAttribute("defaults", def.getDefaults());
+        doWriteAttribute("packageScan", def.getPackageScan());
+        endElement(name);
+    }
     protected void doWriteTransformerDefinitionAttributes(
             TransformerDefinition def)
             throws IOException {
         doWriteAttribute("toType", def.getToType());
         doWriteAttribute("fromType", def.getFromType());
         doWriteAttribute("scheme", def.getScheme());
+        doWriteAttribute("name", def.getName());
     }
     protected void doWriteTransformerDefinition(
             String name,
@@ -4571,6 +4584,7 @@ public class ModelWriter extends BaseWriter {
             switch (v.getClass().getSimpleName()) {
                 case "DataFormatTransformerDefinition" -> doWriteDataFormatTransformerDefinition("dataFormatTransformer", (DataFormatTransformerDefinition) v);
                 case "EndpointTransformerDefinition" -> doWriteEndpointTransformerDefinition("endpointTransformer", (EndpointTransformerDefinition) v);
+                case "LoadTransformerDefinition" -> doWriteLoadTransformerDefinition("loadTransformer", (LoadTransformerDefinition) v);
                 case "CustomTransformerDefinition" -> doWriteCustomTransformerDefinition("customTransformer", (CustomTransformerDefinition) v);
             }
         });
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
index 91b18829099..c0211030ffb 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
@@ -231,6 +231,7 @@ import org.apache.camel.model.rest.SecurityDefinition;
 import org.apache.camel.model.transformer.CustomTransformerDefinition;
 import org.apache.camel.model.transformer.DataFormatTransformerDefinition;
 import org.apache.camel.model.transformer.EndpointTransformerDefinition;
+import org.apache.camel.model.transformer.LoadTransformerDefinition;
 import org.apache.camel.model.transformer.TransformersDefinition;
 import org.apache.camel.model.validator.CustomValidatorDefinition;
 import org.apache.camel.model.validator.EndpointValidatorDefinition;
@@ -2999,6 +3000,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
             properties = {
                     @YamlProperty(name = "class-name", type = "string"),
                     @YamlProperty(name = "from-type", type = "string"),
+                    @YamlProperty(name = "name", type = "string"),
                     @YamlProperty(name = "ref", type = "string"),
                     @YamlProperty(name = "scheme", type = "string"),
                     @YamlProperty(name = "to-type", type = "string")
@@ -3028,6 +3030,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     target.setFromType(val);
                     break;
                 }
+                case "name": {
+                    String val = asText(node);
+                    target.setName(val);
+                    break;
+                }
                 case "ref": {
                     String val = asText(node);
                     target.setRef(val);
@@ -3156,6 +3163,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     @YamlProperty(name = "json-api", type = "object:org.apache.camel.model.dataformat.JsonApiDataFormat"),
                     @YamlProperty(name = "lzf", type = "object:org.apache.camel.model.dataformat.LZFDataFormat"),
                     @YamlProperty(name = "mime-multipart", type = "object:org.apache.camel.model.dataformat.MimeMultipartDataFormat"),
+                    @YamlProperty(name = "name", type = "string"),
                     @YamlProperty(name = "parquet-avro", type = "object:org.apache.camel.model.dataformat.ParquetAvroDataFormat"),
                     @YamlProperty(name = "pgp", type = "object:org.apache.camel.model.dataformat.PGPDataFormat"),
                     @YamlProperty(name = "protobuf", type = "object:org.apache.camel.model.dataformat.ProtobufDataFormat"),
@@ -3402,6 +3410,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     target.setFromType(val);
                     break;
                 }
+                case "name": {
+                    String val = asText(node);
+                    target.setName(val);
+                    break;
+                }
                 case "scheme": {
                     String val = asText(node);
                     target.setScheme(val);
@@ -4623,6 +4636,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
             order = org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
             properties = {
                     @YamlProperty(name = "from-type", type = "string"),
+                    @YamlProperty(name = "name", type = "string"),
                     @YamlProperty(name = "ref", type = "string"),
                     @YamlProperty(name = "scheme", type = "string"),
                     @YamlProperty(name = "to-type", type = "string"),
@@ -4648,6 +4662,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     target.setFromType(val);
                     break;
                 }
+                case "name": {
+                    String val = asText(node);
+                    target.setName(val);
+                    break;
+                }
                 case "ref": {
                     String val = asText(node);
                     target.setRef(val);
@@ -8184,6 +8203,70 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
         }
     }
 
+    @YamlType(
+            types = org.apache.camel.model.transformer.LoadTransformerDefinition.class,
+            order = org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
+            properties = {
+                    @YamlProperty(name = "defaults", type = "boolean"),
+                    @YamlProperty(name = "from-type", type = "string"),
+                    @YamlProperty(name = "name", type = "string"),
+                    @YamlProperty(name = "package-scan", type = "string"),
+                    @YamlProperty(name = "scheme", type = "string"),
+                    @YamlProperty(name = "to-type", type = "string")
+            }
+    )
+    public static class LoadTransformerDefinitionDeserializer extends YamlDeserializerBase<LoadTransformerDefinition> {
+        public LoadTransformerDefinitionDeserializer() {
+            super(LoadTransformerDefinition.class);
+        }
+
+        @Override
+        protected LoadTransformerDefinition newInstance() {
+            return new LoadTransformerDefinition();
+        }
+
+        @Override
+        protected boolean setProperty(LoadTransformerDefinition target, String propertyKey,
+                String propertyName, Node node) {
+            switch(propertyKey) {
+                case "defaults": {
+                    String val = asText(node);
+                    target.setDefaults(val);
+                    break;
+                }
+                case "from-type": {
+                    String val = asText(node);
+                    target.setFromType(val);
+                    break;
+                }
+                case "name": {
+                    String val = asText(node);
+                    target.setName(val);
+                    break;
+                }
+                case "package-scan": {
+                    String val = asText(node);
+                    target.setPackageScan(val);
+                    break;
+                }
+                case "scheme": {
+                    String val = asText(node);
+                    target.setScheme(val);
+                    break;
+                }
+                case "to-type": {
+                    String val = asText(node);
+                    target.setToType(val);
+                    break;
+                }
+                default: {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
     @YamlType(
             nodes = "log",
             inline = true,
@@ -17074,8 +17157,10 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     @YamlProperty(name = "description", type = "string"),
                     @YamlProperty(name = "disabled", type = "boolean"),
                     @YamlProperty(name = "expression", type = "object:org.apache.camel.model.language.ExpressionDefinition"),
+                    @YamlProperty(name = "from-type", type = "string"),
                     @YamlProperty(name = "id", type = "string"),
-                    @YamlProperty(name = "inherit-error-handler", type = "boolean")
+                    @YamlProperty(name = "inherit-error-handler", type = "boolean"),
+                    @YamlProperty(name = "to-type", type = "string")
             }
     )
     public static class TransformDefinitionDeserializer extends YamlDeserializerBase<TransformDefinition> {
@@ -17102,11 +17187,21 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     target.setExpression(val);
                     break;
                 }
+                case "from-type": {
+                    String val = asText(node);
+                    target.setFromType(val);
+                    break;
+                }
                 case "inherit-error-handler": {
                     String val = asText(node);
                     target.setInheritErrorHandler(java.lang.Boolean.valueOf(val));
                     break;
                 }
+                case "to-type": {
+                    String val = asText(node);
+                    target.setToType(val);
+                    break;
+                }
                 case "id": {
                     String val = asText(node);
                     target.setId(val);
@@ -17141,7 +17236,8 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
             properties = {
                     @YamlProperty(name = "custom-transformer", type = "object:org.apache.camel.model.transformer.CustomTransformerDefinition"),
                     @YamlProperty(name = "data-format-transformer", type = "object:org.apache.camel.model.transformer.DataFormatTransformerDefinition"),
-                    @YamlProperty(name = "endpoint-transformer", type = "object:org.apache.camel.model.transformer.EndpointTransformerDefinition")
+                    @YamlProperty(name = "endpoint-transformer", type = "object:org.apache.camel.model.transformer.EndpointTransformerDefinition"),
+                    @YamlProperty(name = "load-transformer", type = "object:org.apache.camel.model.transformer.LoadTransformerDefinition")
             }
     )
     public static class TransformersDefinitionDeserializer extends YamlDeserializerBase<TransformersDefinition> {
@@ -17183,6 +17279,16 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     target.setTransformers(existing);
                     break;
                 }
+                case "load-transformer": {
+                    org.apache.camel.model.transformer.LoadTransformerDefinition val = asType(node, org.apache.camel.model.transformer.LoadTransformerDefinition.class);
+                    java.util.List<org.apache.camel.model.transformer.TransformerDefinition> existing = target.getTransformers();
+                    if (existing == null) {
+                        existing = new java.util.ArrayList<>();
+                    }
+                    existing.add(val);
+                    target.setTransformers(existing);
+                    break;
+                }
                 case "custom-transformer": {
                     org.apache.camel.model.transformer.CustomTransformerDefinition val = asType(node, org.apache.camel.model.transformer.CustomTransformerDefinition.class);
                     java.util.List<org.apache.camel.model.transformer.TransformerDefinition> existing = target.getTransformers();
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
index 3f512865fa4..960fdb05881 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
@@ -226,6 +226,7 @@ public final class ModelDeserializersResolver implements YamlDeserializerResolve
             case "load-balance": return new ModelDeserializers.LoadBalanceDefinitionDeserializer();
             case "loadBalance": return new ModelDeserializers.LoadBalanceDefinitionDeserializer();
             case "org.apache.camel.model.LoadBalanceDefinition": return new ModelDeserializers.LoadBalanceDefinitionDeserializer();
+            case "org.apache.camel.model.transformer.LoadTransformerDefinition": return new ModelDeserializers.LoadTransformerDefinitionDeserializer();
             case "log": return new ModelDeserializers.LogDefinitionDeserializer();
             case "org.apache.camel.model.LogDefinition": return new ModelDeserializers.LogDefinitionDeserializer();
             case "loop": return new ModelDeserializers.LoopDefinitionDeserializer();
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json
index 76e1cb9eef9..5d7127bcd0e 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json
@@ -2491,6 +2491,9 @@
           "id" : {
             "type" : "string"
           },
+          "input-type" : {
+            "$ref" : "#/items/definitions/org.apache.camel.model.InputTypeDefinition"
+          },
           "log-mask" : {
             "type" : "boolean"
           },
@@ -2500,6 +2503,9 @@
           "node-prefix-id" : {
             "type" : "string"
           },
+          "output-type" : {
+            "$ref" : "#/items/definitions/org.apache.camel.model.OutputTypeDefinition"
+          },
           "precondition" : {
             "type" : "string"
           },
@@ -3332,11 +3338,17 @@
           "expression" : {
             "$ref" : "#/items/definitions/org.apache.camel.model.language.ExpressionDefinition"
           },
+          "from-type" : {
+            "type" : "string"
+          },
           "id" : {
             "type" : "string"
           },
           "inherit-error-handler" : {
             "type" : "boolean"
+          },
+          "to-type" : {
+            "type" : "string"
           }
         }
       },
@@ -8008,6 +8020,9 @@
           "from-type" : {
             "type" : "string"
           },
+          "name" : {
+            "type" : "string"
+          },
           "ref" : {
             "type" : "string"
           },
@@ -8091,6 +8106,9 @@
           "mime-multipart" : {
             "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.MimeMultipartDataFormat"
           },
+          "name" : {
+            "type" : "string"
+          },
           "parquet-avro" : {
             "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.ParquetAvroDataFormat"
           },
@@ -8159,6 +8177,9 @@
           "from-type" : {
             "type" : "string"
           },
+          "name" : {
+            "type" : "string"
+          },
           "ref" : {
             "type" : "string"
           },
@@ -8173,6 +8194,29 @@
           }
         }
       },
+      "org.apache.camel.model.transformer.LoadTransformerDefinition" : {
+        "type" : "object",
+        "properties" : {
+          "defaults" : {
+            "type" : "boolean"
+          },
+          "from-type" : {
+            "type" : "string"
+          },
+          "name" : {
+            "type" : "string"
+          },
+          "package-scan" : {
+            "type" : "string"
+          },
+          "scheme" : {
+            "type" : "string"
+          },
+          "to-type" : {
+            "type" : "string"
+          }
+        }
+      },
       "org.apache.camel.model.transformer.TransformersDefinition" : {
         "type" : "object",
         "properties" : {
@@ -8184,6 +8228,9 @@
           },
           "endpoint-transformer" : {
             "$ref" : "#/items/definitions/org.apache.camel.model.transformer.EndpointTransformerDefinition"
+          },
+          "load-transformer" : {
+            "$ref" : "#/items/definitions/org.apache.camel.model.transformer.LoadTransformerDefinition"
           }
         }
       },
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
index 06c320f6d52..ed5bc50550e 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
@@ -2401,6 +2401,9 @@
           "id" : {
             "type" : "string"
           },
+          "inputType" : {
+            "$ref" : "#/items/definitions/org.apache.camel.model.InputTypeDefinition"
+          },
           "logMask" : {
             "type" : "boolean"
           },
@@ -2410,6 +2413,9 @@
           "nodePrefixId" : {
             "type" : "string"
           },
+          "outputType" : {
+            "$ref" : "#/items/definitions/org.apache.camel.model.OutputTypeDefinition"
+          },
           "precondition" : {
             "type" : "string"
           },
@@ -3242,11 +3248,17 @@
           "expression" : {
             "$ref" : "#/items/definitions/org.apache.camel.model.language.ExpressionDefinition"
           },
+          "fromType" : {
+            "type" : "string"
+          },
           "id" : {
             "type" : "string"
           },
           "inheritErrorHandler" : {
             "type" : "boolean"
+          },
+          "toType" : {
+            "type" : "string"
           }
         }
       },
@@ -7915,6 +7927,9 @@
           "fromType" : {
             "type" : "string"
           },
+          "name" : {
+            "type" : "string"
+          },
           "ref" : {
             "type" : "string"
           },
@@ -7998,6 +8013,9 @@
           "mimeMultipart" : {
             "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.MimeMultipartDataFormat"
           },
+          "name" : {
+            "type" : "string"
+          },
           "parquetAvro" : {
             "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.ParquetAvroDataFormat"
           },
@@ -8066,6 +8084,9 @@
           "fromType" : {
             "type" : "string"
           },
+          "name" : {
+            "type" : "string"
+          },
           "ref" : {
             "type" : "string"
           },
@@ -8080,6 +8101,29 @@
           }
         }
       },
+      "org.apache.camel.model.transformer.LoadTransformerDefinition" : {
+        "type" : "object",
+        "properties" : {
+          "defaults" : {
+            "type" : "boolean"
+          },
+          "fromType" : {
+            "type" : "string"
+          },
+          "name" : {
+            "type" : "string"
+          },
+          "packageScan" : {
+            "type" : "string"
+          },
+          "scheme" : {
+            "type" : "string"
+          },
+          "toType" : {
+            "type" : "string"
+          }
+        }
+      },
       "org.apache.camel.model.transformer.TransformersDefinition" : {
         "type" : "object",
         "properties" : {
@@ -8091,6 +8135,9 @@
           },
           "endpointTransformer" : {
             "$ref" : "#/items/definitions/org.apache.camel.model.transformer.EndpointTransformerDefinition"
+          },
+          "loadTransformer" : {
+            "$ref" : "#/items/definitions/org.apache.camel.model.transformer.LoadTransformerDefinition"
           }
         }
       },