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

(camel) 01/09: CAMEL-20514: camel-model - Add support for bean constructors for beans in route templates or kamelets

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

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

commit 28ebdb8cb54b7c8e7b5b10e38c46e693c2f333dd
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu May 2 10:01:08 2024 +0200

    CAMEL-20514: camel-model - Add support for bean constructors for beans in route templates or kamelets
---
 .../apache/camel/catalog/models/templateBean.json  |  17 ++-
 .../camel/catalog/models/templatedRouteBean.json   |  17 ++-
 .../apache/camel/catalog/schemas/camel-spring.xsd  |  85 ++++++++++-
 .../java/org/apache/camel/impl/DefaultModel.java   |   3 -
 .../org/apache/camel/model/templateBean.json       |  17 ++-
 .../org/apache/camel/model/templatedRouteBean.json |  17 ++-
 .../apache/camel/model/BeanFactoryDefinition.java  | 166 ++++++++++++++++-----
 .../java/org/apache/camel/xml/in/ModelParser.java  |  19 ++-
 .../java/org/apache/camel/xml/out/ModelWriter.java |   9 +-
 .../org/apache/camel/yaml/out/ModelWriter.java     |   9 +-
 .../BeanFactoryDefinitionDeserializer.java         |  48 +++++-
 .../RouteTemplateBeanDefinitionDeserializer.java   |   7 +
 .../TemplatedRouteBeanDefinitionDeserializer.java  |   7 +
 .../generated/resources/schema/camelYamlDsl.json   |  42 ++++++
 .../apache/camel/dsl/yaml/KameletLoaderTest.groovy | 132 +++++++++++++++-
 15 files changed, 513 insertions(+), 82 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateBean.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateBean.json
index ef188dacbfe..1ceca0e8443 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateBean.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateBean.json
@@ -12,10 +12,17 @@
     "output": false
   },
   "properties": {
-    "name": { "index": 0, "kind": "attribute", "displayName": "Name", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Bean name" },
-    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "What type to use for creating the bean (FQN classname). Can be prefixed with: #class or #type #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean" },
-    "scriptLanguage": { "index": 2, "kind": "attribute", "displayName": "Script Language", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc." },
-    "properties": { "index": 3, "kind": "element", "displayName": "Properties", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created local bean" },
-    "script": { "index": 4, "kind": "element", "displayName": "Script", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script to execute that creates the bean when using scripting languages. If the script use the prefix resource: such as resource:classpath:com\/foo\/myscript.groovy, resource:file:\/var\/myscript.groovy, then its loaded from the ext [...]
+    "name": { "index": 0, "kind": "attribute", "displayName": "Name", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the bean (bean id)" },
+    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The class name (fully qualified) of the bean" },
+    "initMethod": { "index": 2, "kind": "attribute", "displayName": "Init Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the custom initialization method to invoke after setting bean properties. The method must have no arguments, but may throw any exception." },
+    "destroyMethod": { "index": 3, "kind": "attribute", "displayName": "Destroy Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the custom destroy method to invoke on bean shutdown, such as when Camel is shutting down. The method must have no arguments, but may throw any exception." },
+    "factoryMethod": { "index": 4, "kind": "attribute", "displayName": "Factory Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of method to invoke when creating the bean via a factory bean." },
+    "factoryBean": { "index": 5, "kind": "attribute", "displayName": "Factory Bean", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of factory bean (bean id) to use for creating the bean." },
+    "builderClass": { "index": 6, "kind": "attribute", "displayName": "Builder Class", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Fully qualified class name of builder class to use for creating and configuring the bean. The builder will use the properties values to configure the bean." },
+    "builderMethod": { "index": 7, "kind": "attribute", "displayName": "Builder Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "build", "description": "Name of method when using builder class. This method is invoked after configuring to create the actual bean. This method is often named build (used by default)." },
+    "scriptLanguage": { "index": 8, "kind": "attribute", "displayName": "Script Language", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc." },
+    "constructors": { "index": 9, "kind": "element", "displayName": "Constructors", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.Integer, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional constructor arguments for creating the bean. Arguments correspond to specific index of the constructor argument list, starting from zero." },
+    "properties": { "index": 10, "kind": "element", "displayName": "Properties", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created bean." },
+    "script": { "index": 11, "kind": "element", "displayName": "Script", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script to execute that creates the bean when using scripting languages. If the script use the prefix resource: such as resource:classpath:com\/foo\/myscript.groovy, resource:file:\/var\/myscript.groovy, then its loaded from the ex [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templatedRouteBean.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templatedRouteBean.json
index 719fb8b9d96..04f6d78a1d9 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templatedRouteBean.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templatedRouteBean.json
@@ -12,10 +12,17 @@
     "output": false
   },
   "properties": {
-    "name": { "index": 0, "kind": "attribute", "displayName": "Name", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Bean name" },
-    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "What type to use for creating the bean (FQN classname). Can be prefixed with: #class or #type #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean" },
-    "scriptLanguage": { "index": 2, "kind": "attribute", "displayName": "Script Language", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc." },
-    "properties": { "index": 3, "kind": "element", "displayName": "Properties", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created local bean" },
-    "script": { "index": 4, "kind": "element", "displayName": "Script", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script to execute that creates the bean when using scripting languages. If the script use the prefix resource: such as resource:classpath:com\/foo\/myscript.groovy, resource:file:\/var\/myscript.groovy, then its loaded from the ext [...]
+    "name": { "index": 0, "kind": "attribute", "displayName": "Name", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the bean (bean id)" },
+    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The class name (fully qualified) of the bean" },
+    "initMethod": { "index": 2, "kind": "attribute", "displayName": "Init Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the custom initialization method to invoke after setting bean properties. The method must have no arguments, but may throw any exception." },
+    "destroyMethod": { "index": 3, "kind": "attribute", "displayName": "Destroy Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the custom destroy method to invoke on bean shutdown, such as when Camel is shutting down. The method must have no arguments, but may throw any exception." },
+    "factoryMethod": { "index": 4, "kind": "attribute", "displayName": "Factory Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of method to invoke when creating the bean via a factory bean." },
+    "factoryBean": { "index": 5, "kind": "attribute", "displayName": "Factory Bean", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of factory bean (bean id) to use for creating the bean." },
+    "builderClass": { "index": 6, "kind": "attribute", "displayName": "Builder Class", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Fully qualified class name of builder class to use for creating and configuring the bean. The builder will use the properties values to configure the bean." },
+    "builderMethod": { "index": 7, "kind": "attribute", "displayName": "Builder Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "build", "description": "Name of method when using builder class. This method is invoked after configuring to create the actual bean. This method is often named build (used by default)." },
+    "scriptLanguage": { "index": 8, "kind": "attribute", "displayName": "Script Language", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc." },
+    "constructors": { "index": 9, "kind": "element", "displayName": "Constructors", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.Integer, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional constructor arguments for creating the bean. Arguments correspond to specific index of the constructor argument list, starting from zero." },
+    "properties": { "index": 10, "kind": "element", "displayName": "Properties", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created bean." },
+    "script": { "index": 11, "kind": "element", "displayName": "Script", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script to execute that creates the bean when using scripting languages. If the script use the prefix resource: such as resource:classpath:com\/foo\/myscript.groovy, resource:file:\/var\/myscript.groovy, then its loaded from the ex [...]
   }
 }
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 1751619fc37..464bc3108ca 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
@@ -4018,11 +4018,21 @@ implementation. Default value: Singleton
   </xs:complexType>
   <xs:complexType abstract="true" name="beanFactoryDefinition">
     <xs:sequence>
+      <xs:element minOccurs="0" name="constructors" type="tns:beanConstructorsDefinition">
+        <xs:annotation>
+          <xs:documentation xml:lang="en">
+<![CDATA[
+Optional constructor arguments for creating the bean. Arguments correspond to specific index of the constructor argument
+list, starting from zero.
+]]>
+          </xs:documentation>
+        </xs:annotation>
+      </xs:element>
       <xs:element minOccurs="0" name="properties" type="tns:beanPropertiesDefinition">
         <xs:annotation>
           <xs:documentation xml:lang="en">
 <![CDATA[
-Optional properties to set on the created local bean.
+Optional properties to set on the created bean.
 ]]>
           </xs:documentation>
         </xs:annotation>
@@ -4043,7 +4053,7 @@ resource.
       <xs:annotation>
         <xs:documentation xml:lang="en">
 <![CDATA[
-Bean name.
+The name of the bean (bean id).
 ]]>
         </xs:documentation>
       </xs:annotation>
@@ -4052,8 +4062,65 @@ Bean name.
       <xs:annotation>
         <xs:documentation xml:lang="en">
 <![CDATA[
-What type to use for creating the bean (FQN classname). Can be prefixed with: #class or #type #class or #type then the
-bean is created via the fully qualified classname, such as #class:com.foo.MyBean.
+The class name (fully qualified) of the bean.
+]]>
+        </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="initMethod" type="xs:string">
+      <xs:annotation>
+        <xs:documentation xml:lang="en">
+<![CDATA[
+The name of the custom initialization method to invoke after setting bean properties. The method must have no arguments,
+but may throw any exception.
+]]>
+        </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="destroyMethod" type="xs:string">
+      <xs:annotation>
+        <xs:documentation xml:lang="en">
+<![CDATA[
+The name of the custom destroy method to invoke on bean shutdown, such as when Camel is shutting down. The method must
+have no arguments, but may throw any exception.
+]]>
+        </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="factoryMethod" type="xs:string">
+      <xs:annotation>
+        <xs:documentation xml:lang="en">
+<![CDATA[
+Name of method to invoke when creating the bean via a factory bean.
+]]>
+        </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="factoryBean" type="xs:string">
+      <xs:annotation>
+        <xs:documentation xml:lang="en">
+<![CDATA[
+Name of factory bean (bean id) to use for creating the bean.
+]]>
+        </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="builderClass" type="xs:string">
+      <xs:annotation>
+        <xs:documentation xml:lang="en">
+<![CDATA[
+Fully qualified class name of builder class to use for creating and configuring the bean. The builder will use the
+properties values to configure the bean.
+]]>
+        </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="builderMethod" type="xs:string">
+      <xs:annotation>
+        <xs:documentation xml:lang="en">
+<![CDATA[
+Name of method when using builder class. This method is invoked after configuring to create the actual bean. This method
+is often named build (used by default). Default value: build
 ]]>
         </xs:documentation>
       </xs:annotation>
@@ -4068,6 +4135,16 @@ The script language to use when using inlined script for creating the bean, such
       </xs:annotation>
     </xs:attribute>
   </xs:complexType>
+  <xs:complexType name="beanConstructorsDefinition">
+    <xs:sequence>
+      <xs:element maxOccurs="unbounded" minOccurs="0" name="constructor" type="tns:beanConstructorDefinition"/>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="beanConstructorDefinition">
+    <xs:sequence/>
+    <xs:attribute name="index" type="xs:int"/>
+    <xs:attribute name="value" type="xs:string" use="required"/>
+  </xs:complexType>
   <xs:complexType name="beanPropertiesDefinition">
     <xs:sequence>
       <xs:element maxOccurs="unbounded" minOccurs="0" name="property" type="tns:beanPropertyDefinition"/>
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
index 9a3383055c5..e12f5647f44 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
@@ -572,9 +572,6 @@ public class DefaultModel implements Model {
         if (beanFactory.getProperties() != null) {
             props.putAll(beanFactory.getProperties());
         }
-        if (beanFactory.getPropertyDefinitions() != null) {
-            beanFactory.getPropertyDefinitions().forEach(p -> props.put(p.getKey(), p.getValue()));
-        }
         if (beanFactory.getBeanSupplier() != null) {
             if (props.isEmpty()) {
                 // bean class is optional for supplier
diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/templateBean.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/templateBean.json
index ef188dacbfe..1ceca0e8443 100644
--- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/templateBean.json
+++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/templateBean.json
@@ -12,10 +12,17 @@
     "output": false
   },
   "properties": {
-    "name": { "index": 0, "kind": "attribute", "displayName": "Name", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Bean name" },
-    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "What type to use for creating the bean (FQN classname). Can be prefixed with: #class or #type #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean" },
-    "scriptLanguage": { "index": 2, "kind": "attribute", "displayName": "Script Language", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc." },
-    "properties": { "index": 3, "kind": "element", "displayName": "Properties", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created local bean" },
-    "script": { "index": 4, "kind": "element", "displayName": "Script", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script to execute that creates the bean when using scripting languages. If the script use the prefix resource: such as resource:classpath:com\/foo\/myscript.groovy, resource:file:\/var\/myscript.groovy, then its loaded from the ext [...]
+    "name": { "index": 0, "kind": "attribute", "displayName": "Name", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the bean (bean id)" },
+    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The class name (fully qualified) of the bean" },
+    "initMethod": { "index": 2, "kind": "attribute", "displayName": "Init Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the custom initialization method to invoke after setting bean properties. The method must have no arguments, but may throw any exception." },
+    "destroyMethod": { "index": 3, "kind": "attribute", "displayName": "Destroy Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the custom destroy method to invoke on bean shutdown, such as when Camel is shutting down. The method must have no arguments, but may throw any exception." },
+    "factoryMethod": { "index": 4, "kind": "attribute", "displayName": "Factory Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of method to invoke when creating the bean via a factory bean." },
+    "factoryBean": { "index": 5, "kind": "attribute", "displayName": "Factory Bean", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of factory bean (bean id) to use for creating the bean." },
+    "builderClass": { "index": 6, "kind": "attribute", "displayName": "Builder Class", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Fully qualified class name of builder class to use for creating and configuring the bean. The builder will use the properties values to configure the bean." },
+    "builderMethod": { "index": 7, "kind": "attribute", "displayName": "Builder Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "build", "description": "Name of method when using builder class. This method is invoked after configuring to create the actual bean. This method is often named build (used by default)." },
+    "scriptLanguage": { "index": 8, "kind": "attribute", "displayName": "Script Language", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc." },
+    "constructors": { "index": 9, "kind": "element", "displayName": "Constructors", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.Integer, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional constructor arguments for creating the bean. Arguments correspond to specific index of the constructor argument list, starting from zero." },
+    "properties": { "index": 10, "kind": "element", "displayName": "Properties", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created bean." },
+    "script": { "index": 11, "kind": "element", "displayName": "Script", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script to execute that creates the bean when using scripting languages. If the script use the prefix resource: such as resource:classpath:com\/foo\/myscript.groovy, resource:file:\/var\/myscript.groovy, then its loaded from the ex [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/templatedRouteBean.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/templatedRouteBean.json
index 719fb8b9d96..04f6d78a1d9 100644
--- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/templatedRouteBean.json
+++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/templatedRouteBean.json
@@ -12,10 +12,17 @@
     "output": false
   },
   "properties": {
-    "name": { "index": 0, "kind": "attribute", "displayName": "Name", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Bean name" },
-    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "What type to use for creating the bean (FQN classname). Can be prefixed with: #class or #type #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean" },
-    "scriptLanguage": { "index": 2, "kind": "attribute", "displayName": "Script Language", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc." },
-    "properties": { "index": 3, "kind": "element", "displayName": "Properties", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created local bean" },
-    "script": { "index": 4, "kind": "element", "displayName": "Script", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script to execute that creates the bean when using scripting languages. If the script use the prefix resource: such as resource:classpath:com\/foo\/myscript.groovy, resource:file:\/var\/myscript.groovy, then its loaded from the ext [...]
+    "name": { "index": 0, "kind": "attribute", "displayName": "Name", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the bean (bean id)" },
+    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The class name (fully qualified) of the bean" },
+    "initMethod": { "index": 2, "kind": "attribute", "displayName": "Init Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the custom initialization method to invoke after setting bean properties. The method must have no arguments, but may throw any exception." },
+    "destroyMethod": { "index": 3, "kind": "attribute", "displayName": "Destroy Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the custom destroy method to invoke on bean shutdown, such as when Camel is shutting down. The method must have no arguments, but may throw any exception." },
+    "factoryMethod": { "index": 4, "kind": "attribute", "displayName": "Factory Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of method to invoke when creating the bean via a factory bean." },
+    "factoryBean": { "index": 5, "kind": "attribute", "displayName": "Factory Bean", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of factory bean (bean id) to use for creating the bean." },
+    "builderClass": { "index": 6, "kind": "attribute", "displayName": "Builder Class", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Fully qualified class name of builder class to use for creating and configuring the bean. The builder will use the properties values to configure the bean." },
+    "builderMethod": { "index": 7, "kind": "attribute", "displayName": "Builder Method", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "build", "description": "Name of method when using builder class. This method is invoked after configuring to create the actual bean. This method is often named build (used by default)." },
+    "scriptLanguage": { "index": 8, "kind": "attribute", "displayName": "Script Language", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc." },
+    "constructors": { "index": 9, "kind": "element", "displayName": "Constructors", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.Integer, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional constructor arguments for creating the bean. Arguments correspond to specific index of the constructor argument list, starting from zero." },
+    "properties": { "index": 10, "kind": "element", "displayName": "Properties", "group": "common", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created bean." },
+    "script": { "index": 11, "kind": "element", "displayName": "Script", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script to execute that creates the bean when using scripting languages. If the script use the prefix resource: such as resource:classpath:com\/foo\/myscript.groovy, resource:file:\/var\/myscript.groovy, then its loaded from the ex [...]
   }
 }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/BeanFactoryDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/BeanFactoryDefinition.java
index af8f238b0a6..2763f04314d 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/BeanFactoryDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/BeanFactoryDefinition.java
@@ -16,8 +16,7 @@
  */
 package org.apache.camel.model;
 
-import java.util.LinkedList;
-import java.util.List;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import jakarta.xml.bind.annotation.XmlAccessType;
@@ -28,8 +27,11 @@ import jakarta.xml.bind.annotation.XmlTransient;
 import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
 import org.apache.camel.RouteTemplateContext;
+import org.apache.camel.model.app.BeanConstructorsAdapter;
 import org.apache.camel.model.app.BeanPropertiesAdapter;
 import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.Resource;
+import org.apache.camel.spi.ResourceAware;
 
 /**
  * Base class for nodes that define a bean factory.
@@ -40,8 +42,12 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "configuration")
 @XmlAccessorType(XmlAccessType.FIELD)
 public abstract class BeanFactoryDefinition<
-        T extends BeanFactoryDefinition<T, P>, P> {
+        T extends BeanFactoryDefinition<T, P>, P> implements ResourceAware {
 
+    // TODO: fluent methods for new stuff such as builder/factory
+
+    @XmlTransient
+    private Resource resource;
     @XmlTransient
     private P parent;
     // special for java-dsl to allow using lambda style
@@ -55,10 +61,24 @@ public abstract class BeanFactoryDefinition<
     @XmlAttribute(required = true)
     private String type;
     @XmlAttribute
+    private String initMethod;
+    @XmlAttribute
+    private String destroyMethod;
+    @XmlAttribute
+    private String factoryMethod;
+    @XmlAttribute
+    private String factoryBean;
+    @XmlAttribute
+    private String builderClass;
+    @XmlAttribute
+    @Metadata(defaultValue = "build")
+    private String builderMethod;
+    @XmlAttribute
     @Metadata(label = "advanced")
     private String scriptLanguage;
-    @XmlTransient
-    private List<PropertyDefinition> propertyDefinitions;
+    @XmlElement(name = "constructors")
+    @XmlJavaTypeAdapter(BeanConstructorsAdapter.class)
+    private Map<Integer, Object> constructors;
     @XmlElement(name = "properties")
     @XmlJavaTypeAdapter(BeanPropertiesAdapter.class)
     private Map<String, Object> properties;
@@ -70,12 +90,34 @@ public abstract class BeanFactoryDefinition<
         this.parent = parent;
     }
 
+    /**
+     * To set the type (fully qualified class name) to use for creating the bean.
+     */
+    public void setBeanType(Class<?> beanType) {
+        this.beanClass = beanType;
+    }
+
+    public Class<?> getBeanClass() {
+        return beanClass;
+    }
+
+    public RouteTemplateContext.BeanSupplier<Object> getBeanSupplier() {
+        return beanSupplier;
+    }
+
+    /**
+     * Bean supplier that uses lambda style to create the local bean
+     */
+    public void setBeanSupplier(RouteTemplateContext.BeanSupplier<Object> beanSupplier) {
+        this.beanSupplier = beanSupplier;
+    }
+
     public String getName() {
         return name;
     }
 
     /**
-     * Bean name
+     * The name of the bean (bean id)
      */
     public void setName(String name) {
         this.name = name;
@@ -86,63 +128,103 @@ public abstract class BeanFactoryDefinition<
     }
 
     /**
-     * What type to use for creating the bean (FQN classname). Can be prefixed with: #class or #type
-     *
-     * #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean
+     * The class name (fully qualified) of the bean
      */
     public void setType(String type) {
         this.type = type;
     }
 
+    public String getInitMethod() {
+        return initMethod;
+    }
+
     /**
-     * To set the type (fully qualified class name) to use for creating the bean.
+     * The name of the custom initialization method to invoke after setting bean properties. The method must have no
+     * arguments, but may throw any exception.
      */
-    public void setBeanType(Class<?> beanType) {
-        this.beanClass = beanType;
+    public void setInitMethod(String initMethod) {
+        this.initMethod = initMethod;
     }
 
-    public Class<?> getBeanClass() {
-        return beanClass;
+    public String getDestroyMethod() {
+        return destroyMethod;
     }
 
-    public Map<String, Object> getProperties() {
-        return properties;
+    /**
+     * The name of the custom destroy method to invoke on bean shutdown, such as when Camel is shutting down. The method
+     * must have no arguments, but may throw any exception.
+     */
+    public void setDestroyMethod(String destroyMethod) {
+        this.destroyMethod = destroyMethod;
+    }
+
+    public String getFactoryMethod() {
+        return factoryMethod;
     }
 
     /**
-     * Optional properties to set on the created local bean
+     * Name of method to invoke when creating the bean via a factory bean.
      */
-    public void setProperties(Map<String, Object> properties) {
-        this.properties = properties;
+    public void setFactoryMethod(String factoryMethod) {
+        this.factoryMethod = factoryMethod;
     }
 
-    public List<PropertyDefinition> getPropertyDefinitions() {
-        return propertyDefinitions;
+    public String getFactoryBean() {
+        return factoryBean;
     }
 
     /**
-     * Optional properties to set on the created local bean
+     * Name of factory bean (bean id) to use for creating the bean.
      */
-    public void setPropertyDefinitions(List<PropertyDefinition> propertyDefinitions) {
-        this.propertyDefinitions = propertyDefinitions;
+    public void setFactoryBean(String factoryBean) {
+        this.factoryBean = factoryBean;
     }
 
-    public void addProperty(PropertyDefinition property) {
-        if (propertyDefinitions == null) {
-            propertyDefinitions = new LinkedList<>();
-        }
-        propertyDefinitions.add(property);
+    public String getBuilderClass() {
+        return builderClass;
     }
 
-    public RouteTemplateContext.BeanSupplier<Object> getBeanSupplier() {
-        return beanSupplier;
+    /**
+     * Fully qualified class name of builder class to use for creating and configuring the bean. The builder will use
+     * the properties values to configure the bean.
+     */
+    public void setBuilderClass(String builderClass) {
+        this.builderClass = builderClass;
+    }
+
+    public String getBuilderMethod() {
+        return builderMethod;
     }
 
     /**
-     * Bean supplier that uses lambda style to create the local bean
+     * Name of method when using builder class. This method is invoked after configuring to create the actual bean. This
+     * method is often named build (used by default).
      */
-    public void setBeanSupplier(RouteTemplateContext.BeanSupplier<Object> beanSupplier) {
-        this.beanSupplier = beanSupplier;
+    public void setBuilderMethod(String builderMethod) {
+        this.builderMethod = builderMethod;
+    }
+
+    public Map<Integer, Object> getConstructors() {
+        return constructors;
+    }
+
+    /**
+     * Optional constructor arguments for creating the bean. Arguments correspond to specific index of the constructor
+     * argument list, starting from zero.
+     */
+    public void setConstructors(Map<Integer, Object> constructors) {
+        this.constructors = constructors;
+    }
+
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+
+    /**
+     * Optional properties to set on the created bean.
+     */
+    public void setProperties(Map<String, Object> properties) {
+        this.properties = properties;
     }
 
     public String getScriptLanguage() {
@@ -355,10 +437,10 @@ public abstract class BeanFactoryDefinition<
      */
     @SuppressWarnings("unchecked")
     public T property(String key, String value) {
-        if (propertyDefinitions == null) {
-            propertyDefinitions = new LinkedList<>();
+        if (properties == null) {
+            properties = new LinkedHashMap<>();
         }
-        propertyDefinitions.add(new PropertyDefinition(key, value));
+        properties.put(key, value);
         return (T) this;
     }
 
@@ -375,4 +457,14 @@ public abstract class BeanFactoryDefinition<
         return parent;
     }
 
+    @Override
+    public Resource getResource() {
+        return resource;
+    }
+
+    @Override
+    public void setResource(Resource resource) {
+        this.resource = resource;
+    }
+
 }
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 a2f170324f0..3e5cc2f16a1 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
@@ -899,6 +899,12 @@ public class ModelParser extends BaseParser {
     }
     protected <T extends BeanFactoryDefinition> AttributeHandler<T> beanFactoryDefinitionAttributeHandler() {
         return (def, key, val) -> switch (key) {
+            case "builderClass": def.setBuilderClass(val); yield true;
+            case "builderMethod": def.setBuilderMethod(val); yield true;
+            case "destroyMethod": def.setDestroyMethod(val); yield true;
+            case "factoryBean": def.setFactoryBean(val); yield true;
+            case "factoryMethod": def.setFactoryMethod(val); yield true;
+            case "initMethod": def.setInitMethod(val); yield true;
             case "name": def.setName(val); yield true;
             case "scriptLanguage": def.setScriptLanguage(val); yield true;
             case "type": def.setType(val); yield true;
@@ -907,11 +913,18 @@ public class ModelParser extends BaseParser {
     }
     protected <T extends BeanFactoryDefinition> ElementHandler<T> beanFactoryDefinitionElementHandler() {
         return (def, key) -> switch (key) {
+            case "constructors": def.setConstructors(new BeanConstructorsAdapter().unmarshal(doParseBeanConstructorsDefinition())); yield true;
             case "properties": def.setProperties(new BeanPropertiesAdapter().unmarshal(doParseBeanPropertiesDefinition())); yield true;
             case "script": def.setScript(doParseText()); yield true;
             default: yield false;
         };
     }
+    protected BeanConstructorsDefinition doParseBeanConstructorsDefinition() throws IOException, XmlPullParserException {
+        return doParse(new BeanConstructorsDefinition(), noAttributeHandler(), (def, key) -> switch (key) {
+                case "constructor": doAdd(doParseBeanConstructorDefinition(), def.getConstructors(), def::setConstructors); yield true;
+                default: yield false;
+            }, noValueHandler());
+    }
     protected BeanPropertiesDefinition doParseBeanPropertiesDefinition() throws IOException, XmlPullParserException {
         return doParse(new BeanPropertiesDefinition(), noAttributeHandler(), (def, key) -> switch (key) {
                 case "property": doAdd(doParseBeanPropertyDefinition(), def.getProperties(), def::setProperties); yield true;
@@ -1397,12 +1410,6 @@ public class ModelParser extends BaseParser {
                 default: yield false;
             }, noElementHandler(), noValueHandler());
     }
-    protected BeanConstructorsDefinition doParseBeanConstructorsDefinition() throws IOException, XmlPullParserException {
-        return doParse(new BeanConstructorsDefinition(), noAttributeHandler(), (def, key) -> switch (key) {
-                case "constructor": doAdd(doParseBeanConstructorDefinition(), def.getConstructors(), def::setConstructors); yield true;
-                default: yield false;
-            }, noValueHandler());
-    }
     protected BeanPropertyDefinition doParseBeanPropertyDefinition() throws IOException, XmlPullParserException {
         return doParse(new BeanPropertyDefinition(), (def, key, val) -> switch (key) {
                 case "key": def.setKey(val); yield true;
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 ffd4303fc02..f68bf1a8556 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
@@ -807,12 +807,19 @@ public class ModelWriter extends BaseWriter {
         endElement(name);
     }
     protected void doWriteBeanFactoryDefinitionAttributes(BeanFactoryDefinition<?, ?> def) throws IOException {
+        doWriteAttribute("factoryMethod", def.getFactoryMethod());
         doWriteAttribute("scriptLanguage", def.getScriptLanguage());
-        doWriteAttribute("name", def.getName());
+        doWriteAttribute("builderClass", def.getBuilderClass());
         doWriteAttribute("type", def.getType());
+        doWriteAttribute("factoryBean", def.getFactoryBean());
+        doWriteAttribute("initMethod", def.getInitMethod());
+        doWriteAttribute("name", def.getName());
+        doWriteAttribute("builderMethod", def.getBuilderMethod());
+        doWriteAttribute("destroyMethod", def.getDestroyMethod());
     }
     protected void doWriteBeanFactoryDefinitionElements(BeanFactoryDefinition<?, ?> def) throws IOException {
         doWriteElement("script", def.getScript(), this::doWriteString);
+        doWriteElement("constructors", new BeanConstructorsAdapter().marshal(def.getConstructors()), this::doWriteBeanConstructorsDefinition);
         doWriteElement("properties", new BeanPropertiesAdapter().marshal(def.getProperties()), this::doWriteBeanPropertiesDefinition);
     }
     protected void doWriteBeanFactoryDefinition(String name, BeanFactoryDefinition<?, ?> def) throws IOException {
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 b8697d7e9a4..ff76966b22d 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
@@ -807,12 +807,19 @@ public class ModelWriter extends BaseWriter {
         endElement(name);
     }
     protected void doWriteBeanFactoryDefinitionAttributes(BeanFactoryDefinition<?, ?> def) throws IOException {
+        doWriteAttribute("factoryMethod", def.getFactoryMethod());
         doWriteAttribute("scriptLanguage", def.getScriptLanguage());
-        doWriteAttribute("name", def.getName());
+        doWriteAttribute("builderClass", def.getBuilderClass());
         doWriteAttribute("type", def.getType());
+        doWriteAttribute("factoryBean", def.getFactoryBean());
+        doWriteAttribute("initMethod", def.getInitMethod());
+        doWriteAttribute("name", def.getName());
+        doWriteAttribute("builderMethod", def.getBuilderMethod());
+        doWriteAttribute("destroyMethod", def.getDestroyMethod());
     }
     protected void doWriteBeanFactoryDefinitionElements(BeanFactoryDefinition<?, ?> def) throws IOException {
         doWriteElement("script", def.getScript(), this::doWriteString);
+        doWriteElement("constructors", new BeanConstructorsAdapter().marshal(def.getConstructors()), this::doWriteBeanConstructorsDefinition);
         doWriteElement("properties", new BeanPropertiesAdapter().marshal(def.getProperties()), this::doWriteBeanPropertiesDefinition);
     }
     protected void doWriteBeanFactoryDefinition(String name, BeanFactoryDefinition<?, ?> def) throws IOException {
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeanFactoryDefinitionDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeanFactoryDefinitionDeserializer.java
index 1a8339c41a0..5acaf6c01a9 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeanFactoryDefinitionDeserializer.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeanFactoryDefinitionDeserializer.java
@@ -16,9 +16,11 @@
  */
 package org.apache.camel.dsl.yaml.deserializers;
 
+import java.util.LinkedHashMap;
+import java.util.Map;
+
 import org.apache.camel.dsl.yaml.common.YamlDeserializerBase;
 import org.apache.camel.model.BeanFactoryDefinition;
-import org.apache.camel.model.PropertyDefinition;
 import org.snakeyaml.engine.v2.nodes.Node;
 
 /**
@@ -43,16 +45,44 @@ public abstract class BeanFactoryDefinitionDeserializer<T extends BeanFactoryDef
                 target.setName(val);
                 break;
             }
-            case "property": {
-                java.util.List<PropertyDefinition> val
-                        = asFlatList(node, PropertyDefinition.class);
-                target.setPropertyDefinitions(val);
+            case "constructors": {
+                target.setConstructors(asConstructorMap(asMap(node)));
                 break;
             }
             case "properties": {
                 target.setProperties(asMap(node));
                 break;
             }
+            case "initMethod": {
+                String val = asText(node);
+                target.setInitMethod(val);
+                break;
+            }
+            case "destroyMethod": {
+                String val = asText(node);
+                target.setDestroyMethod(val);
+                break;
+            }
+            case "factoryBean": {
+                String val = asText(node);
+                target.setFactoryBean(val);
+                break;
+            }
+            case "factoryMethod": {
+                String val = asText(node);
+                target.setFactoryMethod(val);
+                break;
+            }
+            case "builderClass": {
+                String val = asText(node);
+                target.setBuilderClass(val);
+                break;
+            }
+            case "builderMethod": {
+                String val = asText(node);
+                target.setBuilderMethod(val);
+                break;
+            }
             case "scriptLanguage": {
                 String val = asText(node);
                 target.setScriptLanguage(val);
@@ -74,4 +104,12 @@ public abstract class BeanFactoryDefinitionDeserializer<T extends BeanFactoryDef
         }
         return true;
     }
+
+    private static Map<Integer, Object> asConstructorMap(Map<String, Object> map) {
+        Map<Integer, Object> answer = new LinkedHashMap<>();
+        map.forEach((k, v) -> {
+            answer.put(Integer.valueOf(k), v);
+        });
+        return answer;
+    }
 }
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteTemplateBeanDefinitionDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteTemplateBeanDefinitionDeserializer.java
index aa63205a6f4..a2a9ad856d3 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteTemplateBeanDefinitionDeserializer.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteTemplateBeanDefinitionDeserializer.java
@@ -32,7 +32,14 @@ import org.apache.camel.spi.annotations.YamlType;
           properties = {
                   @YamlProperty(name = "name", type = "string", required = true),
                   @YamlProperty(name = "type", type = "string", required = true),
+                  @YamlProperty(name = "constructors", type = "object"),
                   @YamlProperty(name = "properties", type = "object"),
+                  @YamlProperty(name = "initMethod", type = "string"),
+                  @YamlProperty(name = "destroyMethod", type = "string"),
+                  @YamlProperty(name = "factoryMethod", type = "string"),
+                  @YamlProperty(name = "factoryBean", type = "string"),
+                  @YamlProperty(name = "builderClass", type = "string"),
+                  @YamlProperty(name = "builderMethod", type = "string"),
                   @YamlProperty(name = "scriptLanguage", type = "string"),
                   @YamlProperty(name = "script", type = "string")
           })
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/TemplatedRouteBeanDefinitionDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/TemplatedRouteBeanDefinitionDeserializer.java
index 514febd4787..ef863e147d4 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/TemplatedRouteBeanDefinitionDeserializer.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/TemplatedRouteBeanDefinitionDeserializer.java
@@ -32,7 +32,14 @@ import org.apache.camel.spi.annotations.YamlType;
           properties = {
                   @YamlProperty(name = "name", type = "string", required = true),
                   @YamlProperty(name = "type", type = "string", required = true),
+                  @YamlProperty(name = "constructors", type = "object"),
                   @YamlProperty(name = "properties", type = "object"),
+                  @YamlProperty(name = "initMethod", type = "string"),
+                  @YamlProperty(name = "destroyMethod", type = "string"),
+                  @YamlProperty(name = "factoryMethod", type = "string"),
+                  @YamlProperty(name = "factoryBean", type = "string"),
+                  @YamlProperty(name = "builderClass", type = "string"),
+                  @YamlProperty(name = "builderMethod", type = "string"),
                   @YamlProperty(name = "scriptLanguage", type = "string"),
                   @YamlProperty(name = "script", type = "string")
           })
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 e25e27c2345..9bcc0866225 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
@@ -5191,6 +5191,27 @@
         "type" : "object",
         "additionalProperties" : false,
         "properties" : {
+          "builderClass" : {
+            "type" : "string"
+          },
+          "builderMethod" : {
+            "type" : "string"
+          },
+          "constructors" : {
+            "type" : "object"
+          },
+          "destroyMethod" : {
+            "type" : "string"
+          },
+          "factoryBean" : {
+            "type" : "string"
+          },
+          "factoryMethod" : {
+            "type" : "string"
+          },
+          "initMethod" : {
+            "type" : "string"
+          },
           "name" : {
             "type" : "string"
           },
@@ -6651,6 +6672,27 @@
         "type" : "object",
         "additionalProperties" : false,
         "properties" : {
+          "builderClass" : {
+            "type" : "string"
+          },
+          "builderMethod" : {
+            "type" : "string"
+          },
+          "constructors" : {
+            "type" : "object"
+          },
+          "destroyMethod" : {
+            "type" : "string"
+          },
+          "factoryBean" : {
+            "type" : "string"
+          },
+          "factoryMethod" : {
+            "type" : "string"
+          },
+          "initMethod" : {
+            "type" : "string"
+          },
           "name" : {
             "type" : "string"
           },
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletLoaderTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletLoaderTest.groovy
index 6e3e5294671..868a7e07880 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletLoaderTest.groovy
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletLoaderTest.groovy
@@ -66,9 +66,8 @@ class KameletLoaderTest extends YamlTestSupport {
                     beans:
                       - name: kameletBean
                         type: org.apache.camel.dsl.yaml.KameletBean
-                        property:
-                          - key: kbProp
-                            value: kbValue
+                        properties:
+                          kbProp: kbValue
                       - name: kameletBean2
                         type: org.apache.camel.dsl.yaml.KameletBean
                         properties:
@@ -103,13 +102,26 @@ class KameletLoaderTest extends YamlTestSupport {
                     it.name == 'overrideEndpoint' && it.defaultValue == 'false'
                 }
 
+                with(it.templateBeans[0]) {
+                    it.name == 'kameletBean'
+                    it.type == 'org.apache.camel.dsl.yaml.KameletBean'
+                    it.properties.size() == 1
+                    it.properties['kbProp'] == 'kbValue'
+                }
+                with(it.templateBeans[1]) {
+                    it.name == 'kameletBean2'
+                    it.type == 'org.apache.camel.dsl.yaml.KameletBean'
+                    it.properties.size() == 2
+                    it.properties['kbProp2'] == 'kbValue2'
+                }
+
                 with(route) {
                     input.endpointUri == 'kamelet:source'
-                    input.lineNumber == 47
+                    input.lineNumber == 46
                     outputs.size() == 1
                     with (outputs[0], ToDefinition) {
                         endpointUri ==~ /aws2-s3:.*/
-                        lineNumber == 50
+                        lineNumber == 49
                     }
                 }
             }
@@ -320,4 +332,114 @@ class KameletLoaderTest extends YamlTestSupport {
         then:
             MockEndpoint.assertIsSatisfied(context)
     }
+
+    def "kamelet with bean constructors"() {
+        when:
+        loadKamelets('''
+                apiVersion: camel.apache.org/v1
+                kind: Kamelet
+                metadata:
+                  name: aws-s3-sink                  
+                spec:
+                  definition:
+                    title: "AWS S3 Sink"
+                    description: "AWS S3 Sink"
+                    required:
+                      - bucketNameOrArn
+                      - accessKey
+                      - secretKey
+                      - region
+                    type: object
+                    properties:
+                      bucketNameOrArn:
+                        title: Bucket Name
+                        description: The S3 Bucket name or ARN.
+                        type: string
+                      accessKey:
+                        title: Access Key
+                        description: The access key obtained from AWS.
+                        type: string
+                        format: password
+                        x-descriptors:
+                        - urn:alm:descriptor:com.tectonic.ui:password
+                      overrideEndpoint:
+                        title: Override Endpoint
+                        type: boolean
+                        default: false
+                        x-descriptors:
+                        - 'urn:alm:descriptor:com.tectonic.ui:checkbox'
+                  template:
+                    beans:
+                      - name: kameletBean
+                        type: org.apache.camel.dsl.yaml.KameletBean
+                        constructors:
+                          '0': 123
+                          '1': 'Hello World'
+                      - name: kameletBean2
+                        type: org.apache.camel.dsl.yaml.KameletBean
+                        constructors:
+                          '0': 123
+                          '1': 'Hello World'
+                          '2': '#bean:kameletBean'
+                        properties:
+                          kbProp2: kbValue2
+                    from:
+                      uri: "kamelet:source"
+                      steps:
+                      - to:
+                          uri: "aws2-s3:{{bucketNameOrArn}}"
+                          parameters:
+                            secretKey: "{{secretKey}}"
+                            accessKey: "{{accessKey}}"
+                            region: "{{region}}"
+                            uriEndpointOverride: "{{uriEndpointOverride}}"
+                            overrideEndpoint: "{{overrideEndpoint}}"
+                            autoCreateBucket: "{{autoCreateBucket}}"
+            ''')
+        then:
+        context.routeTemplateDefinitions.size() == 1
+
+        with (context.routeTemplateDefinitions[0]) {
+            id == 'aws-s3-sink'
+
+            templateParameters.size() == 3
+
+            templateParameters.any {
+                it.name == 'bucketNameOrArn' && it.defaultValue == null
+            }
+            templateParameters.any {
+                it.name == 'overrideEndpoint' && it.defaultValue == 'false'
+            }
+
+            with(it.templateBeans[0]) {
+                it.name == 'kameletBean'
+                it.type == 'org.apache.camel.dsl.yaml.KameletBean'
+                it.properties == null
+                it.constructors.size() == 2
+                it.constructors[0] == '123'
+                it.constructors[1] == 'Hello World'
+            }
+            with(it.templateBeans[1]) {
+                it.name == 'kameletBean2'
+                it.type == 'org.apache.camel.dsl.yaml.KameletBean'
+                it.properties.size() == 1
+                it.properties['kbProp2'] == 'kbValue2'
+                it.constructors.size() == 3
+                it.constructors[0] == '123'
+                it.constructors[1] == 'Hello World'
+                it.constructors[2] == '#bean:kameletBean'
+            }
+
+            with(route) {
+                input.endpointUri == 'kamelet:source'
+                input.lineNumber == 49
+                outputs.size() == 1
+                with (outputs[0], ToDefinition) {
+                    endpointUri ==~ /aws2-s3:.*/
+                    lineNumber == 52
+                }
+            }
+        }
+    }
+
 }