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

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


The following commit(s) were added to refs/heads/main by this push:
     new 2e7578c9426 Builder class (#12270)
2e7578c9426 is described below

commit 2e7578c9426bb327e0ca8c43b4a93063d70b946e
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Nov 30 11:29:18 2023 +0100

    Builder class (#12270)
    
    * CAMEL-20130: camel-core - PropertyBuilderSupport add support for fluent 
builder classes.
    
    * CAMEL-20130: camel-yaml-dsl - Allow to use bean builder classes when 
defining beans
    
    * CAMEL-20130: camel-xml-io-dsl - Allow to use bean builder classes when 
defining beans
    
    * CAMEL-20130: camel-yaml-dsl - Allow to use bean builder classes when 
defining beans
    
    * CAMEL-20130: camel-yaml-dsl - Allow to use bean builder classes when 
defining beans
---
 .../org/apache/camel/catalog/models-app/bean.json  |  10 +-
 .../resources/org/apache/camel/model/app/bean.json |  10 +-
 .../camel/model/app/RegistryBeanDefinition.java    |  29 ++++++
 .../PropertyBindingSupportBuildMethodTest.java     | 104 +++++++++++++++++++++
 .../camel/support/PropertyBindingSupport.java      |  31 ++++++
 .../java/org/apache/camel/xml/in/ModelParser.java  |   2 +
 .../java/org/apache/camel/xml/out/ModelWriter.java |   2 +
 .../org/apache/camel/xml/LwModelToXMLDumper.java   |   6 ++
 .../camel/xml/jaxb/JaxbModelToXMLDumper.java       |   6 ++
 .../org/apache/camel/yaml/out/ModelWriter.java     |   2 +
 .../org/apache/camel/yaml/LwModelToYAMLDumper.java |   6 ++
 .../modules/ROOT/pages/property-binding.adoc       |  51 ++++++++++
 .../src/main/docs/java-xml-io-dsl.adoc             |  21 +++++
 .../camel/dsl/xml/io/XmlRoutesBuilderLoader.java   |  14 ++-
 .../apache/camel/dsl/xml/io/XmlLoadAppTest.java    |  31 +++++-
 .../org/apache/camel/dsl/xml/io/beans/MyBean.java  |  35 +++++++
 .../camel/dsl/xml/io/beans/MyBeanBuilder.java      |  44 +++++++++
 .../org/apache/camel/dsl/xml/io/camel-app10.xml    |  37 ++++++++
 .../dsl/yaml/deserializers/ModelDeserializers.java |  12 +++
 .../dsl/yaml/deserializers/BeansDeserializer.java  |  14 ++-
 .../generated/resources/schema/camelYamlDsl.json   |   6 ++
 .../camel-yaml-dsl/src/main/docs/yaml-dsl.adoc     |  22 +++++
 .../org/apache/camel/dsl/yaml/BeansTest.groovy     |  21 +++++
 .../dsl/yaml/support/model/MyBeanBuilder.groovy    |  46 +++++++++
 24 files changed, 549 insertions(+), 13 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models-app/bean.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models-app/bean.json
index ffb007e78e4..f67b2ec342e 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models-app/bean.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models-app/bean.json
@@ -18,9 +18,11 @@
     "destroyMethod": { "index": 3, "kind": "attribute", "displayName": 
"Destroy Method", "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", "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", "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." },
-    "scriptLanguage": { "index": 6, "kind": "attribute", "displayName": 
"Script Language", "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": 7, "kind": "element", "displayName": 
"Constructors", "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": 8, "kind": "element", "displayName": 
"Properties", "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": 9, "kind": "element", "displayName": "Script", 
"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 external 
resource." }
+    "builderClass": { "index": 6, "kind": "attribute", "displayName": "Builder 
Class", "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", "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", "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", "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", "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", 
"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 external 
resource." }
   }
 }
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/bean.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/bean.json
index ffb007e78e4..f67b2ec342e 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/bean.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/bean.json
@@ -18,9 +18,11 @@
     "destroyMethod": { "index": 3, "kind": "attribute", "displayName": 
"Destroy Method", "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", "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", "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." },
-    "scriptLanguage": { "index": 6, "kind": "attribute", "displayName": 
"Script Language", "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": 7, "kind": "element", "displayName": 
"Constructors", "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": 8, "kind": "element", "displayName": 
"Properties", "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": 9, "kind": "element", "displayName": "Script", 
"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 external 
resource." }
+    "builderClass": { "index": 6, "kind": "attribute", "displayName": "Builder 
Class", "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", "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", "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", "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", "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", 
"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 external 
resource." }
   }
 }
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/app/RegistryBeanDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/app/RegistryBeanDefinition.java
index 6c1b8da40f4..936978bcfc7 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/app/RegistryBeanDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/app/RegistryBeanDefinition.java
@@ -54,6 +54,11 @@ public class RegistryBeanDefinition implements ResourceAware 
{
     @XmlAttribute
     private String factoryBean;
     @XmlAttribute
+    private String builderClass;
+    @XmlAttribute
+    @Metadata(defaultValue = "build")
+    private String builderMethod;
+    @XmlAttribute
     @Metadata(label = "advanced")
     private String scriptLanguage;
     @XmlElement(name = "constructors")
@@ -134,6 +139,30 @@ public class RegistryBeanDefinition implements 
ResourceAware {
         this.factoryBean = factoryBean;
     }
 
+    public String getBuilderClass() {
+        return builderClass;
+    }
+
+    /**
+     * 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;
+    }
+
+    /**
+     * 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 setBuilderMethod(String builderMethod) {
+        this.builderMethod = builderMethod;
+    }
+
     public Map<Integer, Object> getConstructors() {
         return constructors;
     }
diff --git 
a/core/camel-main/src/test/java/org/apache/camel/main/PropertyBindingSupportBuildMethodTest.java
 
b/core/camel-main/src/test/java/org/apache/camel/main/PropertyBindingSupportBuildMethodTest.java
new file mode 100644
index 00000000000..507b686f704
--- /dev/null
+++ 
b/core/camel-main/src/test/java/org/apache/camel/main/PropertyBindingSupportBuildMethodTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.main;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.support.PropertyBindingSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit test for PropertyBindingSupport
+ */
+public class PropertyBindingSupportBuildMethodTest {
+
+    @Test
+    public void testBuildClass() throws Exception {
+        CamelContext context = new DefaultCamelContext();
+
+        context.start();
+
+        MyDriver driver = PropertyBindingSupport.build()
+                .withCamelContext(context)
+                .withTarget(new MyDriverBuilder())
+                .withFluentBuilder(true)
+                .withProperty("url", "localhost:1234")
+                .withProperty("username", "scott")
+                .withProperty("password", "tiger")
+                .build(MyDriver.class);
+
+        Assertions.assertNotNull(driver);
+        Assertions.assertEquals("localhost:1234", driver.getUrl());
+        Assertions.assertEquals("scott", driver.getUsername());
+        Assertions.assertEquals("tiger", driver.getPassword());
+
+        context.stop();
+    }
+
+    public static class MyDriver {
+
+        private final String url;
+        private final String username;
+        private final String password;
+
+        public MyDriver(String url, String username, String password) {
+            this.url = url;
+            this.username = username;
+            this.password = password;
+        }
+
+        public String getUrl() {
+            return url;
+        }
+
+        public String getUsername() {
+            return username;
+        }
+
+        public String getPassword() {
+            return password;
+        }
+    }
+
+    public static class MyDriverBuilder {
+
+        private String url;
+        private String username;
+        private String password;
+
+        public MyDriverBuilder url(String url) {
+            this.url = url;
+            return this;
+        }
+
+        public MyDriverBuilder username(String username) {
+            this.username = username;
+            return this;
+        }
+
+        public MyDriverBuilder password(String password) {
+            this.password = password;
+            return this;
+        }
+
+        public MyDriver build() {
+            return new MyDriver(url, username, password);
+        }
+    }
+
+}
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
index 7d766645ee1..df8297c3df0 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
@@ -38,6 +38,7 @@ import java.util.stream.Collectors;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.PropertyBindingException;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.spi.BeanIntrospection;
 import org.apache.camel.spi.PropertiesComponent;
 import org.apache.camel.spi.PropertyConfigurer;
@@ -1874,6 +1875,36 @@ public final class PropertyBindingSupport {
             return this;
         }
 
+        /**
+         * Binds the properties to the target object, and builds the output as 
the given type, by invoking the build
+         * method (uses build as name)
+         *
+         * @param type the type of the output class
+         */
+        public <T> T build(Class<T> type) {
+            return build(type, "build");
+        }
+
+        /**
+         * Binds the properties to the target object, and builds the output as 
the given type, by invoking the build
+         * method (via reflection).
+         *
+         * @param type        the type of the output class
+         * @param buildMethod the name of the builder method to invoke
+         */
+        public <T> T build(Class<T> type, String buildMethod) {
+            // first bind
+            bind();
+
+            // then invoke the build method on target via reflection
+            try {
+                Object out = ObjectHelper.invokeMethodSafe(buildMethod, 
target);
+                return camelContext.getTypeConverter().convertTo(type, out);
+            } catch (Exception e) {
+                throw RuntimeCamelException.wrapRuntimeException(e);
+            }
+        }
+
         /**
          * Binds the properties to the target object, and removes the property 
that was bound from properties.
          *
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 d5ea55476bd..db2af55817d 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
@@ -1645,6 +1645,8 @@ public class ModelParser extends BaseParser {
     protected RegistryBeanDefinition doParseRegistryBeanDefinition() throws 
IOException, XmlPullParserException {
         return doParse(new RegistryBeanDefinition(), (def, key, val) -> {
             switch (key) {
+                case "builderClass": def.setBuilderClass(val); break;
+                case "builderMethod": def.setBuilderMethod(val); break;
                 case "destroyMethod": def.setDestroyMethod(val); break;
                 case "factoryBean": def.setFactoryBean(val); break;
                 case "factoryMethod": def.setFactoryMethod(val); break;
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 0b1ae97db63..c8de5e968d0 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
@@ -2585,7 +2585,9 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("factoryMethod", def.getFactoryMethod());
         doWriteAttribute("initMethod", def.getInitMethod());
         doWriteAttribute("scriptLanguage", def.getScriptLanguage());
+        doWriteAttribute("builderClass", def.getBuilderClass());
         doWriteAttribute("name", def.getName());
+        doWriteAttribute("builderMethod", def.getBuilderMethod());
         doWriteAttribute("destroyMethod", def.getDestroyMethod());
         doWriteAttribute("type", def.getType());
         doWriteAttribute("factoryBean", def.getFactoryBean());
diff --git 
a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java 
b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
index 0ca0a23cc76..cb14b3e4110 100644
--- 
a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
+++ 
b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
@@ -331,6 +331,12 @@ public class LwModelToXMLDumper implements 
ModelToXMLDumper {
             if (b.getFactoryMethod() != null) {
                 buffer.write(String.format(" factoryMethod=\"%s\"", 
b.getFactoryMethod()));
             }
+            if (b.getBuilderClass() != null) {
+                buffer.write(String.format(" builderClass=\"%s\"", 
b.getBuilderClass()));
+            }
+            if (b.getBuilderMethod() != null) {
+                buffer.write(String.format(" builderMethod=\"%s\"", 
b.getBuilderMethod()));
+            }
             if (b.getInitMethod() != null) {
                 buffer.write(String.format(" initMethod=\"%s\"", 
b.getInitMethod()));
             }
diff --git 
a/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
 
b/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
index 9a0c4440553..5b3cea30587 100644
--- 
a/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
+++ 
b/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
@@ -316,6 +316,12 @@ public class JaxbModelToXMLDumper implements 
ModelToXMLDumper {
             if (b.getFactoryMethod() != null) {
                 buffer.write(String.format(" factoryMethod=\"%s\"", 
b.getFactoryMethod()));
             }
+            if (b.getBuilderClass() != null) {
+                buffer.write(String.format(" builderClass=\"%s\"", 
b.getBuilderClass()));
+            }
+            if (b.getBuilderMethod() != null) {
+                buffer.write(String.format(" builderMethod=\"%s\"", 
b.getBuilderMethod()));
+            }
             if (b.getInitMethod() != null) {
                 buffer.write(String.format(" initMethod=\"%s\"", 
b.getInitMethod()));
             }
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 f9de1b056d8..844d01839ee 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
@@ -2585,7 +2585,9 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("factoryMethod", def.getFactoryMethod());
         doWriteAttribute("initMethod", def.getInitMethod());
         doWriteAttribute("scriptLanguage", def.getScriptLanguage());
+        doWriteAttribute("builderClass", def.getBuilderClass());
         doWriteAttribute("name", def.getName());
+        doWriteAttribute("builderMethod", def.getBuilderMethod());
         doWriteAttribute("destroyMethod", def.getDestroyMethod());
         doWriteAttribute("type", def.getType());
         doWriteAttribute("factoryBean", def.getFactoryBean());
diff --git 
a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
 
b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
index 5268f4d87e9..e8581cd572b 100644
--- 
a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
+++ 
b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
@@ -320,6 +320,12 @@ public class LwModelToYAMLDumper implements 
ModelToYAMLDumper {
             if (b.getFactoryMethod() != null) {
                 buffer.write(String.format("      factoryMethod: \"%s\"%n", 
b.getFactoryMethod()));
             }
+            if (b.getBuilderClass() != null) {
+                buffer.write(String.format("      builderClass: \"%s\"%n", 
b.getBuilderClass()));
+            }
+            if (b.getBuilderMethod() != null) {
+                buffer.write(String.format("      builderMethod: \"%s\"%n", 
b.getBuilderMethod()));
+            }
             if (b.getInitMethod() != null) {
                 buffer.write(String.format("      initMethod: \"%s\"%n", 
b.getInitMethod()));
             }
diff --git a/docs/user-manual/modules/ROOT/pages/property-binding.adoc 
b/docs/user-manual/modules/ROOT/pages/property-binding.adoc
index 8687eee222c..31d578cebd6 100644
--- a/docs/user-manual/modules/ROOT/pages/property-binding.adoc
+++ b/docs/user-manual/modules/ROOT/pages/property-binding.adoc
@@ -193,6 +193,57 @@ 
PropertyBindingSupport.build().withCamelContext(context).withTarget(foo)
     .bind();
 ----
 
+=== Using fluent builder class
+
+When you are in need to configure a bean via _fluent builder class_, such as 
the following example:
+
+[source,java]
+----
+public class MyDriverBuilder {
+
+ private String url;
+ private String username;
+ private String password;
+
+ public MyDriverBuilder url(String url) {
+     this.url = url;
+     return this;
+ }
+
+ public MyDriverBuilder username(String username) {
+     this.username = username;
+     return this;
+ }
+
+ public MyDriverBuilder password(String password) {
+     this.password = password;
+     return this;
+ }
+
+ public MyDriver build() {
+     return new MyDriver(url, username, password);
+ }
+}
+----
+
+And you want to create an instance of `MyDriver` via the `MyDriverBuilder` 
class, then this can be done as follows:
+
+[source,java]
+----
+MyDriver driver = PropertyBindingSupport.build()
+  .withCamelContext(context)
+  .withTarget(new MyDriverBuilder())
+  .withFluentBuilder(true)
+  .withProperty("url", "localhost:1234")
+  .withProperty("username", "scott")
+  .withProperty("password", "tiger")
+  .build(MyDriver.class);
+----
+
+Notice how we use the `build(MyDriver.class)` to build the bean via the target 
class `.withTarget(new MyDriverBuilder())`.
+The build method will by default invoke `build` as the builder method, but you 
can specify the name, such as `.build(MyDriver.class, "myBuilderMethod");`
+
+
 == More details
 
 Property binding is notably used when running Camel in standalone mode with 
Camel Main, or using Camel Spring Boot, Camel K,
diff --git a/dsl/camel-xml-io-dsl/src/main/docs/java-xml-io-dsl.adoc 
b/dsl/camel-xml-io-dsl/src/main/docs/java-xml-io-dsl.adoc
index 138021c6990..289c0c92ae5 100644
--- a/dsl/camel-xml-io-dsl/src/main/docs/java-xml-io-dsl.adoc
+++ b/dsl/camel-xml-io-dsl/src/main/docs/java-xml-io-dsl.adoc
@@ -188,6 +188,27 @@ public class MyBean {
 
 NOTE: The factory method must be `public static` and from the same class as 
the created class itself.
 
+=== Creating beans from builder classes
+
+A bean can also be created from another builder class as shown below:
+
+[source,xml]
+----
+       <bean name="myBean" type="com.acme.MyBean"
+          builderClass="com.acme.MyBeanBuilder" builderMethod="createMyBean">
+        <properties>
+          <property key="id" value="123"/>
+          <property key="name" value="Acme"/>
+        </constructors>
+       </bean>
+----
+
+NOTE: The builder class must be `public` and have a no-arg default constructor.
+
+The builder class is then used to create the actual bean by using fluent 
builder style configuration.
+So the properties will be set on the builder class, and the bean is created by 
invoking the `builderMethod`
+at the end. The invocation of this method is done via Java reflection.
+
 === Creating beans from factory bean
 
 A bean can also be created from a factory bean as shown below:
diff --git 
a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
 
b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
index 2b3d858b849..e19fb750a58 100644
--- 
a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
+++ 
b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
@@ -385,7 +385,19 @@ public class XmlRoutesBuilderLoader extends 
RouteBuilderLoaderSupport {
             if (target == null) {
                 throw new NoSuchBeanException(def.getName(), "Creating bean 
using script returned null");
             }
-
+        } else if (def.getBuilderClass() != null) {
+            // builder class and method
+            Class<?> clazz = 
context.getClassResolver().resolveMandatoryClass(def.getBuilderClass());
+            Object builder = context.getInjector().newInstance(clazz);
+            String bm = def.getBuilderMethod() != null ? 
def.getBuilderMethod() : "build";
+
+            // create bean via builder and assign as target output
+            target = PropertyBindingSupport.build()
+                    .withCamelContext(context)
+                    .withTarget(builder)
+                    .withRemoveParameters(true)
+                    .withProperties(def.getProperties())
+                    .build(Object.class, bm);
         } else {
             // factory bean/method
             if (def.getFactoryBean() != null && def.getFactoryMethod() != 
null) {
diff --git 
a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java
 
b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java
index 4039d20dd97..83700f09df1 100644
--- 
a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java
+++ 
b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java
@@ -243,10 +243,35 @@ public class XmlLoadAppTest {
             assertEquals(1, context.getRoutes().size());
 
             // test that loaded route works
-            MockEndpoint y8 = context.getEndpoint("mock:y9", 
MockEndpoint.class);
-            y8.expectedBodiesReceived("Hi World from groovy Uranus");
+            MockEndpoint y9 = context.getEndpoint("mock:y9", 
MockEndpoint.class);
+            y9.expectedBodiesReceived("Hi World from groovy Uranus");
             context.createProducerTemplate().sendBody("direct:x9", "I'm 
Uranus");
-            y8.assertIsSatisfied();
+            y9.assertIsSatisfied();
+
+            context.stop();
+        }
+    }
+
+    @Test
+    public void testLoadCamelAppWithBeanBuilderClass() throws Exception {
+        try (DefaultCamelContext context = new DefaultCamelContext()) {
+            context.start();
+
+            Resource resource = 
PluginHelper.getResourceLoader(context).resolveResource(
+                    "/org/apache/camel/dsl/xml/io/camel-app10.xml");
+
+            RoutesLoader routesLoader = PluginHelper.getRoutesLoader(context);
+            routesLoader.preParseRoute(resource, false);
+            routesLoader.loadRoutes(resource);
+
+            assertNotNull(context.getRoute("r10"), "Loaded r10 route should be 
there");
+            assertEquals(1, context.getRoutes().size());
+
+            // test that loaded route works
+            MockEndpoint y10 = context.getEndpoint("mock:y10", 
MockEndpoint.class);
+            y10.expectedBodiesReceived("Hi World. I am Camel and 44 years 
old!");
+            context.createProducerTemplate().sendBody("direct:x10", "Hi");
+            y10.assertIsSatisfied();
 
             context.stop();
         }
diff --git 
a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/MyBean.java
 
b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/MyBean.java
new file mode 100644
index 00000000000..66212bda235
--- /dev/null
+++ 
b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/MyBean.java
@@ -0,0 +1,35 @@
+/*
+ * 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.dsl.xml.io.beans;
+
+public class MyBean {
+
+    private String field1;
+    private String field2;
+    private int age;
+
+    public MyBean(String field1, String field2, int age) {
+        this.field1 = field1;
+        this.field2 = field2;
+        this.age = age;
+    }
+
+    public String hi(String body) {
+        return body + " " + field1 + ". I am " + field2 + " and " + age + " 
years old!";
+    }
+
+}
diff --git 
a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/MyBeanBuilder.java
 
b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/MyBeanBuilder.java
new file mode 100644
index 00000000000..e5e06393878
--- /dev/null
+++ 
b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/beans/MyBeanBuilder.java
@@ -0,0 +1,44 @@
+/*
+ * 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.dsl.xml.io.beans;
+
+public class MyBeanBuilder {
+
+    private String field1;
+    private String field2;
+    private int age;
+
+    public MyBeanBuilder field1(String field1) {
+        this.field1 = field1;
+        return this;
+    }
+
+    public MyBeanBuilder field2(String field2) {
+        this.field2 = field2;
+        return this;
+    }
+
+    public MyBeanBuilder age(int age) {
+        this.age = age;
+        return this;
+    }
+
+    public MyBean createTheBean() {
+        return new MyBean(field1, field2, age);
+    }
+
+}
diff --git 
a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app10.xml
 
b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app10.xml
new file mode 100644
index 00000000000..9a5843ce93e
--- /dev/null
+++ 
b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app10.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<camel xmlns="http://camel.apache.org/schema/spring"; 
xmlns:s="http://www.springframework.org/schema/beans";>
+
+    <bean name="xml-bean-from-registry" 
type="org.apache.camel.dsl.xml.io.beans.MyBean"
+          builderClass="org.apache.camel.dsl.xml.io.beans.MyBeanBuilder" 
builderMethod="createTheBean">
+        <properties>
+            <property key="field1" value="World"/>
+            <property key="field2" value="Camel"/>
+            <property key="age" value="44"/>
+        </properties>
+    </bean>
+
+    <route id="r10">
+        <from uri="direct:x10"/>
+        <bean ref="xml-bean-from-registry"/>
+        <to uri="mock:y10"/>
+    </route>
+
+</camel>
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 8fec7a9903c..9e01da00d36 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
@@ -12308,6 +12308,8 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
             types = org.apache.camel.model.app.RegistryBeanDefinition.class,
             order = 
org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
             properties = {
+                    @YamlProperty(name = "builder-class", type = "string"),
+                    @YamlProperty(name = "builder-method", type = "string"),
                     @YamlProperty(name = "constructors", type = "object"),
                     @YamlProperty(name = "destroy-method", type = "string"),
                     @YamlProperty(name = "factory-bean", type = "string"),
@@ -12334,6 +12336,16 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
         protected boolean setProperty(RegistryBeanDefinition target, String 
propertyKey,
                 String propertyName, Node node) {
             switch(propertyKey) {
+                case "builder-class": {
+                    String val = asText(node);
+                    target.setBuilderClass(val);
+                    break;
+                }
+                case "builder-method": {
+                    String val = asText(node);
+                    target.setBuilderMethod(val);
+                    break;
+                }
                 case "constructors": {
                     java.util.Map val = asMap(node);
                     target.setConstructors(val);
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
index ca2eddc7879..64fdaef4f16 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
@@ -147,7 +147,19 @@ public class BeansDeserializer extends 
YamlDeserializerSupport implements Constr
             if (target == null) {
                 throw new NoSuchBeanException(def.getName(), "Creating bean 
using script returned null");
             }
-
+        } else if (def.getBuilderClass() != null) {
+            // builder class and method
+            Class<?> clazz = 
context.getClassResolver().resolveMandatoryClass(def.getBuilderClass());
+            Object builder = context.getInjector().newInstance(clazz);
+            String bm = def.getBuilderMethod() != null ? 
def.getBuilderMethod() : "build";
+
+            // create bean via builder and assign as target output
+            target = PropertyBindingSupport.build()
+                    .withCamelContext(context)
+                    .withTarget(builder)
+                    .withRemoveParameters(true)
+                    .withProperties(def.getProperties())
+                    .build(Object.class, bm);
         } else {
             // factory bean/method
             if (def.getFactoryBean() != null && def.getFactoryMethod() != 
null) {
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 da067a148aa..1447e89ffa1 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
@@ -7942,6 +7942,12 @@
         "type" : "object",
         "additionalProperties" : false,
         "properties" : {
+          "builderClass" : {
+            "type" : "string"
+          },
+          "builderMethod" : {
+            "type" : "string"
+          },
           "constructors" : {
             "type" : "object"
           },
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc
index 7886335c75d..25d60874613 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc
@@ -267,6 +267,28 @@ public class MyHelper {
 
 NOTE: The factory method must be `public static`.
 
+=== Creating beans from builder classes
+
+A bean can also be created from another builder class as shown below:
+
+[source,yaml]
+----
+- beans:
+  - name: myBean
+    type: com.acme.MyBean
+    builderClass: com.acme.MyBeanBuilder
+    builderMethod: createMyBean
+    properties:
+      id: 123
+      name: 'Acme'
+----
+
+NOTE: The builder class must be `public` and have a no-arg default constructor.
+
+The builder class is then used to create the actual bean by using fluent 
builder style configuration.
+So the properties will be set on the builder class, and the bean is created by 
invoking the `builderMethod`
+at the end. The invocation of this method is done via Java reflection.
+
 === Creating beans using script language
 
 For advanced use-cases then Camel allows to inline a script language, such as 
groovy, java, javascript, etc, to create the bean.
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/BeansTest.groovy
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/BeansTest.groovy
index 194b6bf9595..e7b05bf71e2 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/BeansTest.groovy
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/BeansTest.groovy
@@ -18,6 +18,7 @@ package org.apache.camel.dsl.yaml
 
 import org.apache.camel.dsl.yaml.support.YamlTestSupport
 import org.apache.camel.dsl.yaml.support.model.MyBean
+import org.apache.camel.dsl.yaml.support.model.MyBeanBuilder
 import org.apache.camel.dsl.yaml.support.model.MyCtrBean
 import org.apache.camel.dsl.yaml.support.model.MyDestroyBean
 import org.apache.camel.dsl.yaml.support.model.MyFacBean
@@ -229,4 +230,24 @@ class BeansTest extends YamlTestSupport {
         }
     }
 
+    def "beans with builder class"() {
+        when:
+        loadRoutes """
+                - beans:
+                  - name: myBean
+                    type: ${MyBean.class.name}
+                    builderClass: ${MyBeanBuilder.class.name}
+                    builderMethod: createTheBean
+                    properties:
+                      field1: builder1 
+                      field2: builder2 
+            """
+
+        then:
+        with(context.registry.lookupByName('myBean'), MyBean) {
+            it.field1 == 'builder1'
+            it.field2 == 'builder2'
+        }
+    }
+
 }
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/model/MyBeanBuilder.groovy
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/model/MyBeanBuilder.groovy
new file mode 100644
index 00000000000..8bd930cb953
--- /dev/null
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/model/MyBeanBuilder.groovy
@@ -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.dsl.yaml.support.model
+
+class MyBeanBuilder {
+    private String field1
+    private String field2
+    private MyFooBar nested
+
+    MyBeanBuilder field1(String field1) {
+        this.field1 = field1
+        return this
+    }
+
+    MyBeanBuilder field2(String field2) {
+        this.field2 = field2
+        return this
+    }
+
+    MyBeanBuilder nested(MyFooBar fooBar) {
+        this.nested = fooBar;
+        return this
+    }
+
+    MyBean createTheBean() {
+        MyBean answer = new MyBean()
+        answer.field1 = field1
+        answer.field2 = field2
+        answer.nested = nested
+        return answer
+    }
+}


Reply via email to