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 2023/10/05 10:09:59 UTC

[camel] branch main updated: CAMEL-19953: route templates / kamelets - Add scriptLanguage to specify language instead of type so its more intuitive and similar to the new bean model. (#11650)

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 cc23fc2dd89 CAMEL-19953: route templates / kamelets - Add scriptLanguage to specify language instead of type so its more intuitive and similar to the new bean model. (#11650)
cc23fc2dd89 is described below

commit cc23fc2dd89268a19df4e640c055173e4c1c6e95
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Oct 5 12:09:51 2023 +0200

    CAMEL-19953: route templates / kamelets - Add scriptLanguage to specify language instead of type so its more intuitive and similar to the new bean model. (#11650)
---
 .../apache/camel/catalog/models/templateBean.json  |  4 +-
 .../camel/catalog/models/templatedRouteBean.json   |  4 +-
 .../apache/camel/catalog/schemas/camel-spring.xsd  | 10 +--
 .../routebuilder/SpringTemplatedRouteTest.xml      |  3 +-
 .../java/org/apache/camel/impl/DefaultModel.java   | 24 +++---
 .../org/apache/camel/model/templateBean.json       |  4 +-
 .../org/apache/camel/model/templatedRouteBean.json |  4 +-
 .../apache/camel/model/BeanFactoryDefinition.java  | 96 +++++++++-------------
 .../java/org/apache/camel/xml/in/ModelParser.java  |  2 +-
 .../java/org/apache/camel/xml/out/ModelWriter.java |  2 +-
 .../org/apache/camel/yaml/out/ModelWriter.java     |  2 +-
 .../ROOT/pages/camel-4x-upgrade-guide-4_1.adoc     | 64 +++++++++++++++
 .../modules/ROOT/pages/route-template.adoc         | 37 ++-------
 .../BeanFactoryDefinitionDeserializer.java         | 12 +--
 .../RouteTemplateBeanDefinitionDeserializer.java   |  6 +-
 .../TemplatedRouteBeanDefinitionDeserializer.java  |  6 +-
 .../generated/resources/schema/camelYamlDsl.json   | 12 +--
 .../apache/camel/dsl/yaml/RouteTemplateTest.groovy | 31 ++-----
 .../camel/dsl/yaml/TemplatedRouteTest.groovy       | 14 ++--
 19 files changed, 171 insertions(+), 166 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 ddce4b6ea6c..2e3870a9b9d 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
@@ -13,8 +13,8 @@
   },
   "properties": {
     "name": { "index": 0, "kind": "attribute", "displayName": "Name", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Bean name" },
-    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "What type to use for creating the bean. Can be one of: #class,#type,bean,groovy,joor,language,mvel,ognl. #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean The others are scripting languages that gives more power to create th [...]
-    "beanType": { "index": 2, "kind": "attribute", "displayName": "Bean Type", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To set the type (fully qualified class name) of the returned bean created by the script. Knowing the type of the bean can be needed when dependency injection by type is in use, or when looking in registry via class type." },
+    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "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", "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." },
     "property": { "index": 3, "kind": "element", "displayName": "Property", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created local bean" },
     "properties": { "index": 4, "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 local bean" },
     "script": { "index": 5, "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/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 265a0c662af..f334d16e717 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
@@ -13,8 +13,8 @@
   },
   "properties": {
     "name": { "index": 0, "kind": "attribute", "displayName": "Name", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Bean name" },
-    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "What type to use for creating the bean. Can be one of: #class,#type,bean,groovy,joor,language,mvel,ognl. #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean The others are scripting languages that gives more power to create th [...]
-    "beanType": { "index": 2, "kind": "attribute", "displayName": "Bean Type", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To set the type (fully qualified class name) of the returned bean created by the script. Knowing the type of the bean can be needed when dependency injection by type is in use, or when looking in registry via class type." },
+    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "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", "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." },
     "property": { "index": 3, "kind": "element", "displayName": "Property", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created local bean" },
     "properties": { "index": 4, "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 local bean" },
     "script": { "index": 5, "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/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 b4a6bce6207..4545637eac9 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
@@ -3945,19 +3945,17 @@ Bean name.
       <xs:annotation>
         <xs:documentation xml:lang="en">
 <![CDATA[
-What type to use for creating the bean. Can be one of: #class,#type,bean,groovy,joor,language,mvel,ognl. #class or #type
-then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean The others are scripting
-languages that gives more power to create the bean with an inlined code in the script section, such as using groovy.
+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.
 ]]>
         </xs:documentation>
       </xs:annotation>
     </xs:attribute>
-    <xs:attribute name="beanType" type="xs:string">
+    <xs:attribute name="scriptLanguage" type="xs:string">
       <xs:annotation>
         <xs:documentation xml:lang="en">
 <![CDATA[
-To set the type (fully qualified class name) of the returned bean created by the script. Knowing the type of the bean
-can be needed when dependency injection by type is in use, or when looking in registry via class type.
+The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc.
 ]]>
         </xs:documentation>
       </xs:annotation>
diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/routebuilder/SpringTemplatedRouteTest.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/routebuilder/SpringTemplatedRouteTest.xml
index 65e61b47442..610809fab3f 100644
--- a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/routebuilder/SpringTemplatedRouteTest.xml
+++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/routebuilder/SpringTemplatedRouteTest.xml
@@ -40,7 +40,8 @@
             <bean name="myBean" type="#class:org.apache.camel.spring.routebuilder.SpringTemplatedRouteTest$MySpecialBean">
                 <property key="name" value="John"/>
             </bean>
-            <bean name="myScriptBean" type="bean">
+            <bean name="myScriptBean" type="org.apache.camel.spring.routebuilder.SpringTemplatedRouteTest$MyScriptBean"
+                  scriptLanguage="bean">
                 <script>org.apache.camel.spring.routebuilder.SpringTemplatedRouteTest$MyScriptBean?method=create</script>
             </bean>
         </templatedRoute>
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 657db043fed..1ab011334be 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
@@ -557,20 +557,22 @@ public class DefaultModel implements Model {
                     routeTemplateContext.bind(beanFactory.getName(), beanFactory.getBeanSupplier());
                 }
             }
-        } else if (beanFactory.getScript() != null) {
-            final String script = beanFactory.getScript();
+        } else if (beanFactory.getScript() != null && beanFactory.getScriptLanguage() != null) {
             final CamelContext camelContext = routeTemplateContext.getCamelContext();
-            final Language lan = camelContext.resolveLanguage(beanFactory.getType());
+            final Language lan = camelContext.resolveLanguage(beanFactory.getScriptLanguage());
             final Class<?> clazz;
-            if (beanFactory.getBeanType() != null) {
-                clazz = camelContext.getClassResolver().resolveMandatoryClass(beanFactory.getBeanType());
-            } else {
-                if (beanFactory.getBeanClass() != null) {
-                    clazz = beanFactory.getBeanClass();
-                } else {
-                    clazz = Object.class;
+            if (beanFactory.getBeanClass() != null) {
+                clazz = beanFactory.getBeanClass();
+            } else if (beanFactory.getType() != null) {
+                String fqn = beanFactory.getType();
+                if (fqn.contains(":")) {
+                    fqn = StringHelper.after(fqn, ":");
                 }
+                clazz = camelContext.getClassResolver().resolveMandatoryClass(fqn);
+            } else {
+                clazz = Object.class;
             }
+            final String script = beanFactory.getScript();
             final ScriptingLanguage slan = lan instanceof ScriptingLanguage ? (ScriptingLanguage) lan : null;
             if (slan != null) {
                 // scripting language should be evaluated with route template context as binding
@@ -580,7 +582,7 @@ public class DefaultModel implements Model {
                     Map<String, Object> bindings = new HashMap<>();
                     // use rtx as the short-hand name, as context would imply its CamelContext
                     bindings.put("rtc", routeTemplateContext);
-                    Object local = slan.evaluate(script, bindings, clazz);
+                    Object local = slan.evaluate(script, bindings, Object.class);
                     if (!props.isEmpty()) {
                         PropertyBindingSupport.setPropertiesOnTarget(camelContext, local, props);
                     }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/templateBean.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/templateBean.json
index ddce4b6ea6c..2e3870a9b9d 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/templateBean.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/templateBean.json
@@ -13,8 +13,8 @@
   },
   "properties": {
     "name": { "index": 0, "kind": "attribute", "displayName": "Name", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Bean name" },
-    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "What type to use for creating the bean. Can be one of: #class,#type,bean,groovy,joor,language,mvel,ognl. #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean The others are scripting languages that gives more power to create th [...]
-    "beanType": { "index": 2, "kind": "attribute", "displayName": "Bean Type", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To set the type (fully qualified class name) of the returned bean created by the script. Knowing the type of the bean can be needed when dependency injection by type is in use, or when looking in registry via class type." },
+    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "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", "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." },
     "property": { "index": 3, "kind": "element", "displayName": "Property", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created local bean" },
     "properties": { "index": 4, "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 local bean" },
     "script": { "index": 5, "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/templatedRouteBean.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/templatedRouteBean.json
index 265a0c662af..f334d16e717 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/templatedRouteBean.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/templatedRouteBean.json
@@ -13,8 +13,8 @@
   },
   "properties": {
     "name": { "index": 0, "kind": "attribute", "displayName": "Name", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Bean name" },
-    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "What type to use for creating the bean. Can be one of: #class,#type,bean,groovy,joor,language,mvel,ognl. #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean The others are scripting languages that gives more power to create th [...]
-    "beanType": { "index": 2, "kind": "attribute", "displayName": "Bean Type", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To set the type (fully qualified class name) of the returned bean created by the script. Knowing the type of the bean can be needed when dependency injection by type is in use, or when looking in registry via class type." },
+    "type": { "index": 1, "kind": "attribute", "displayName": "Type", "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", "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." },
     "property": { "index": 3, "kind": "element", "displayName": "Property", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.PropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Optional properties to set on the created local bean" },
     "properties": { "index": 4, "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 local bean" },
     "script": { "index": 5, "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/BeanFactoryDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/BeanFactoryDefinition.java
index e835f64853b..372f51d9ff3 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
@@ -56,7 +56,7 @@ public abstract class BeanFactoryDefinition<
     private String type;
     @XmlAttribute
     @Metadata(label = "advanced")
-    private String beanType;
+    private String scriptLanguage;
     @XmlElement(name = "property")
     private List<PropertyDefinition> propertyDefinitions;
     @XmlElement(name = "properties")
@@ -86,36 +86,16 @@ public abstract class BeanFactoryDefinition<
     }
 
     /**
-     * What type to use for creating the bean. Can be one of: #class,#type,bean,groovy,joor,language,mvel,ognl.
+     * 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 others are scripting languages that gives more power to create the bean with an inlined code in the script
-     * section, such as using groovy.
      */
     public void setType(String type) {
         this.type = type;
     }
 
-    public String getBeanType() {
-        return beanType;
-    }
-
-    /**
-     * To set the type (fully qualified class name) of the returned bean created by the script.
-     *
-     * Knowing the type of the bean can be needed when dependency injection by type is in use, or when looking in
-     * registry via class type.
-     */
-    public void setBeanType(String beanType) {
-        this.beanType = beanType;
-    }
-
     /**
-     * To set the type (fully qualified class name) of the returned bean created by the script.
-     *
-     * Knowing the type of the bean can be needed when dependency injection by type is in use, or when looking in
-     * registry via class type.
+     * To set the type (fully qualified class name) to use for creating the bean.
      */
     public void setBeanType(Class<?> beanType) {
         this.beanClass = beanType;
@@ -165,6 +145,17 @@ public abstract class BeanFactoryDefinition<
         this.beanSupplier = beanSupplier;
     }
 
+    public String getScriptLanguage() {
+        return scriptLanguage;
+    }
+
+    /**
+     * The script language to use when using inlined script for creating the bean, such as groovy, java, javascript etc.
+     */
+    public void setScriptLanguage(String scriptLanguage) {
+        this.scriptLanguage = scriptLanguage;
+    }
+
     /**
      * The script to execute that creates the bean when using scripting languages.
      *
@@ -183,12 +174,9 @@ public abstract class BeanFactoryDefinition<
     // ----------------------------------------------------
 
     /**
-     * What type to use for creating the bean. Can be one of: #class,#type,bean,groovy,joor,language,mvel,ognl.
+     * What type to use for creating the bean. Can be one of: #class or #type
      *
      * #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean
-     *
-     * The others are scripting languages that gives more power to create the bean with an inlined code in the script
-     * section, such as using groovy.
      */
     @SuppressWarnings("unchecked")
     public T type(String prefix, Class<?> type) {
@@ -197,21 +185,15 @@ public abstract class BeanFactoryDefinition<
                 prefix = prefix + ":";
             }
             setType(prefix + type.getName());
-        } else {
-            // its a script
-            setType(prefix);
         }
         setBeanType(type);
         return (T) this;
     }
 
     /**
-     * What type to use for creating the bean. Can be one of: #class,#type,bean,groovy,joor,language,mvel,ognl.
+     * What type to use for creating the bean. Can be one of: #class or #type
      *
      * #class or #type then the bean is created via the fully qualified classname, such as #class:com.foo.MyBean
-     *
-     * The others are scripting languages that gives more power to create the bean with an inlined code in the script
-     * section, such as using groovy.
      */
     @SuppressWarnings("unchecked")
     public T type(String type) {
@@ -246,12 +228,9 @@ public abstract class BeanFactoryDefinition<
     }
 
     /**
-     * To set the return type of the script (fully qualified class name).
-     *
-     * Knowing the type of the bean can be needed when dependency injection by type is in use, or when looking in
-     * registry via class type.
+     * To set the type (fully qualified class name) to use for creating the bean.
      *
-     * @param type the fully qualified type of the returned bean from the script
+     * @param type the fully qualified type of the returned bean
      */
     @SuppressWarnings("unchecked")
     public T beanType(Class<?> type) {
@@ -259,20 +238,6 @@ public abstract class BeanFactoryDefinition<
         return (T) this;
     }
 
-    /**
-     * To set the return type of the script (fully qualified class name).
-     *
-     * Knowing the type of the bean can be needed when dependency injection by type is in use, or when looking in
-     * registry via class type.
-     *
-     * @param type the fully qualified type of the returned bean from the script
-     */
-    @SuppressWarnings("unchecked")
-    public T beanType(String type) {
-        setBeanType(type);
-        return (T) this;
-    }
-
     /**
      * Calls a method on a bean for creating the local bean
      *
@@ -289,7 +254,8 @@ public abstract class BeanFactoryDefinition<
      * @param method the name of the method to call
      */
     public P bean(Class<?> type, String method) {
-        setType("bean");
+        setScriptLanguage("bean");
+        setBeanType(type);
         if (method != null) {
             setScript(type.getName() + "?method=" + method);
         } else {
@@ -307,7 +273,7 @@ public abstract class BeanFactoryDefinition<
      * @param script the script
      */
     public P groovy(String script) {
-        setType("groovy");
+        setScriptLanguage("groovy");
         setScript(script);
         return parent;
     }
@@ -321,11 +287,23 @@ public abstract class BeanFactoryDefinition<
      * @param script the script
      */
     public P joor(String script) {
-        setType("joor");
+        setScriptLanguage("joor");
         setScript(script);
         return parent;
     }
 
+    /**
+     * Calls java (Java source that is runtime compiled to Java bytecode) for creating the local bean
+     *
+     * If the script use the prefix <tt>resource:</tt> such as <tt>resource:classpath:com/foo/myscript.groovy</tt>,
+     * <tt>resource:file:/var/myscript.groovy</tt>, then its loaded from the external resource.
+     *
+     * @param script the script
+     */
+    public P java(String script) {
+        return joor(script);
+    }
+
     /**
      * Calls a custom language for creating the local bean
      *
@@ -336,7 +314,7 @@ public abstract class BeanFactoryDefinition<
      * @param script   the script
      */
     public P language(String language, String script) {
-        setType(language);
+        setScriptLanguage(language);
         setScript(script);
         return parent;
     }
@@ -350,7 +328,7 @@ public abstract class BeanFactoryDefinition<
      * @param script the script
      */
     public P mvel(String script) {
-        setType("mvel");
+        setScriptLanguage("mvel");
         setScript(script);
         return parent;
     }
@@ -364,7 +342,7 @@ public abstract class BeanFactoryDefinition<
      * @param script the script
      */
     public P ognl(String script) {
-        setType("ognl");
+        setScriptLanguage("ognl");
         setScript(script);
         return parent;
     }
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 a7483c74b4f..55d4fead3e9 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
@@ -1093,8 +1093,8 @@ public class ModelParser extends BaseParser {
     protected <T extends BeanFactoryDefinition> AttributeHandler<T> beanFactoryDefinitionAttributeHandler() {
         return (def, key, val) -> {
             switch (key) {
-                case "beanType": def.setBeanType(val); break;
                 case "name": def.setName(val); break;
+                case "scriptLanguage": def.setScriptLanguage(val); break;
                 case "type": def.setType(val); break;
                 default: return false;
             }
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
index a88d2559a1c..2224f585be1 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
@@ -1064,9 +1064,9 @@ public class ModelWriter extends BaseWriter {
     protected void doWriteBeanFactoryDefinitionAttributes(
             BeanFactoryDefinition<?, ?> def)
             throws IOException {
+        doWriteAttribute("scriptLanguage", def.getScriptLanguage());
         doWriteAttribute("name", def.getName());
         doWriteAttribute("type", def.getType());
-        doWriteAttribute("beanType", def.getBeanType());
     }
     protected void doWriteBeanFactoryDefinitionElements(
             BeanFactoryDefinition<?, ?> def)
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 43aadc53dfb..665bd65a0b6 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
@@ -1064,9 +1064,9 @@ public class ModelWriter extends BaseWriter {
     protected void doWriteBeanFactoryDefinitionAttributes(
             BeanFactoryDefinition<?, ?> def)
             throws IOException {
+        doWriteAttribute("scriptLanguage", def.getScriptLanguage());
         doWriteAttribute("name", def.getName());
         doWriteAttribute("type", def.getType());
-        doWriteAttribute("beanType", def.getBeanType());
     }
     protected void doWriteBeanFactoryDefinitionElements(
             BeanFactoryDefinition<?, ?> def)
diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc
index 97752bd7ad8..497462e8e77 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc
@@ -14,6 +14,70 @@ to `org.apache.camel.spi.Injector`.
 Added `isIgnoreLoadingError` and `setIgnoreLoadingError` methods to `org.apache.camel.spi.RoutesLoader`,
 and `org.apache.camel.main.RoutesCollector`.
 
+=== XML and YAML DSL
+
+==== Creating beans from script
+
+In route templates (or kamelets), for advanced use cases, you are able to create beans from an inlined script.
+
+The name of the script was defined in `type`, but has been changed to a new `scriptLanguage` attribute.
+And `beanType` has been removed as you must use `type` instead.
+
+Before:
+
+[tabs]
+====
+XML::
++
+[source,xml]
+----
+    <bean name="myBean" type="groovy" beanType="com.foo.MyBean">
+        <script>
+          <!-- groovy code here to create the bean -->
+        </script>
+    </bean>
+----
+YAML::
++
+[source,yaml]
+----
+- beans:
+  - name: "myClient"
+    beanType: "com.foo.MyBean"
+    type: "groovy"
+    script: |
+      # groovy script here
+----
+====
+
+After:
+
+[tabs]
+====
+XML::
++
+[source,xml]
+----
+    <bean name="myBean" type="com.foo.MyBean"
+          scriptLanguage="groovy">
+        <script>
+          <!-- groovy code here to create the bean -->
+        </script>
+    </bean>
+----
+YAML::
++
+[source,yaml]
+----
+- beans:
+  - name: "myClient"
+    type: "com.foo.MyBean"
+    scriptLanguage: "groovy"
+    script: |
+      # groovy script here
+----
+====
+
 === camel-management
 
 Dumping routes to JMX no longer includes `customId="true"` in the XML nodes.
diff --git a/docs/user-manual/modules/ROOT/pages/route-template.adoc b/docs/user-manual/modules/ROOT/pages/route-template.adoc
index 1fc276c92ef..4c6883d68f6 100644
--- a/docs/user-manual/modules/ROOT/pages/route-template.adoc
+++ b/docs/user-manual/modules/ROOT/pages/route-template.adoc
@@ -465,36 +465,15 @@ templatedRoute("s3template")
 ----
 <1> Note that the third parameter of the `bean` method is not directly the bean but rather a factory method that will be used to create the bean, here we use a lambda expression as factory method.
 
-And in Spring XML DSL
-
-[source,xml]
-----
-<camelContext>
-  <templatedRoute routeTemplateRef="s3template" routeId="mys3route">
-    <parameter name="region" value="US-EAST-1"/>
-    <parameter name="bucket" value="myBucket"/>
-    <bean name="myClient" type="groovy"> <!--1-->
-        <script>
-            import software.amazon.awssdk.services.s3.S3Client
-            S3Client.builder()
-                .region(rtc.getProperty("region", Region.class))
-                .build()
-        </script>
-    </bean>
-  </templatedRoute>
-</camelContext>
-----
-<1> For non-Java DSL, in case of a complex bean factory, you can still rely on a language like `groovy` to define your bean factory inside a `script` element.
-
 And in XML DSL
 
 [source,xml]
 ----
-<templatedRoutes xmlns="http://camel.apache.org/schema/spring">
   <templatedRoute routeTemplateRef="s3template" routeId="mys3route">
     <parameter name="region" value="US-EAST-1"/>
     <parameter name="bucket" value="myBucket"/>
-    <bean name="myClient" type="groovy"> <!--1-->
+    <bean name="myClient" type="software.amazon.awssdk.services.s3.S3Client"
+          scriptLanguage="groovy"> <!--1-->
         <script>
             import software.amazon.awssdk.services.s3.S3Client
             S3Client.builder()
@@ -503,7 +482,6 @@ And in XML DSL
         </script>
     </bean>
   </templatedRoute>
-</templatedRoutes>
 ----
 <1> For non-Java DSL, in case of a complex bean factory, you can still rely on a language like `groovy` to define your bean factory inside a `script` element.
 
@@ -521,7 +499,8 @@ And in YAML DSL
         value: "myBucket"
     beans:
       - name: "myClient"
-        type: "groovy"
+        type: "software.amazon.awssdk.services.s3.S3Client"
+        scriptLanguage: "groovy"
         script: | # <1>
             import software.amazon.awssdk.services.s3.S3Client
             S3Client.builder()
@@ -796,11 +775,7 @@ then you can create the local bean using Java lambda style as previously documen
 
 ==== Configuring the type of the created bean
 
-When using scripting languages to create the local bean, then Camel would not know what type (fully qualified class name)
-the created bean is. The type is therefore unassigned (is set as `java.lang.Object`) which is a slight limitation.
-
-If you use dependency injection by type, or have the need for looking up the local bean from the Camel `Registry` via its type,
-then you must provide this information in the route template with `beanType` as shown:
+The `type` must be set to define what FQN class the created bean.
 
 [source,xml]
 ----
@@ -808,7 +783,7 @@ then you must provide this information in the route template with `beanType` as
   <routeTemplate id="s3template">
     <templateParameter name="region"/>
     <templateParameter name="bucket"/>
-    <templateBean name="myClient" type="bean" beanType="software.amazon.awssdk.services.s3.S3Client">
+    <templateBean name="myClient" scriptLanguage="bean" type="software.amazon.awssdk.services.s3.S3Client">
         <script>com.foo.MyAwsHelper?method=createS3Client</script>
     </templateBean>
     <route>
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 85a942cd439..142c49b793e 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
@@ -36,12 +36,6 @@ public abstract class BeanFactoryDefinitionDeserializer<T extends BeanFactoryDef
             T target, String propertyKey,
             String propertyName, Node node) {
         switch (propertyKey) {
-            case "beanType":
-            case "bean-type": {
-                String val = asText(node);
-                target.setBeanType(val);
-                break;
-            }
             case "name": {
                 String val = asText(node);
                 target.setName(val);
@@ -57,6 +51,12 @@ public abstract class BeanFactoryDefinitionDeserializer<T extends BeanFactoryDef
                 target.setProperties(asMap(node));
                 break;
             }
+            case "scriptLanguage":
+            case "script-language": {
+                String val = asText(node);
+                target.setScriptLanguage(val);
+                break;
+            }
             case "script": {
                 String val = asText(node);
                 target.setScript(val);
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 67df9bb142b..185f5ccbd1b 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
@@ -30,12 +30,12 @@ import org.apache.camel.spi.annotations.YamlType;
           order = YamlDeserializerResolver.ORDER_DEFAULT,
           nodes = { "template-bean", "templateBean" },
           properties = {
-                  @YamlProperty(name = "bean-type", type = "string"),
                   @YamlProperty(name = "name", type = "string", required = true),
+                  @YamlProperty(name = "type", type = "string", required = true),
                   @YamlProperty(name = "property", type = "array:org.apache.camel.model.PropertyDefinition"),
                   @YamlProperty(name = "properties", type = "object"),
-                  @YamlProperty(name = "script", type = "string"),
-                  @YamlProperty(name = "type", type = "string", required = true)
+                  @YamlProperty(name = "scriptLanguage", type = "string"),
+                  @YamlProperty(name = "script", type = "string")
           })
 public class RouteTemplateBeanDefinitionDeserializer extends BeanFactoryDefinitionDeserializer<RouteTemplateBeanDefinition> {
     public RouteTemplateBeanDefinitionDeserializer() {
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 31da27bf1e7..6511c9d2bb9 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
@@ -30,12 +30,12 @@ import org.apache.camel.spi.annotations.YamlType;
           order = YamlDeserializerResolver.ORDER_DEFAULT,
           nodes = { "templated-route-bean", "templatedRouteBean" },
           properties = {
-                  @YamlProperty(name = "bean-type", type = "string"),
                   @YamlProperty(name = "name", type = "string", required = true),
+                  @YamlProperty(name = "type", type = "string", required = true),
                   @YamlProperty(name = "property", type = "array:org.apache.camel.model.PropertyDefinition"),
                   @YamlProperty(name = "properties", type = "object"),
-                  @YamlProperty(name = "script", type = "string"),
-                  @YamlProperty(name = "type", type = "string", required = true)
+                  @YamlProperty(name = "scriptLanguage", type = "string"),
+                  @YamlProperty(name = "script", type = "string")
           })
 public class TemplatedRouteBeanDefinitionDeserializer extends BeanFactoryDefinitionDeserializer<TemplatedRouteBeanDefinition> {
     public TemplatedRouteBeanDefinitionDeserializer() {
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 a31f5382127..c0d7232ddcb 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
@@ -4894,9 +4894,6 @@
         "type" : "object",
         "additionalProperties" : false,
         "properties" : {
-          "beanType" : {
-            "type" : "string"
-          },
           "name" : {
             "type" : "string"
           },
@@ -4912,6 +4909,9 @@
           "script" : {
             "type" : "string"
           },
+          "scriptLanguage" : {
+            "type" : "string"
+          },
           "type" : {
             "type" : "string"
           }
@@ -6163,9 +6163,6 @@
         "type" : "object",
         "additionalProperties" : false,
         "properties" : {
-          "beanType" : {
-            "type" : "string"
-          },
           "name" : {
             "type" : "string"
           },
@@ -6181,6 +6178,9 @@
           "script" : {
             "type" : "string"
           },
+          "scriptLanguage" : {
+            "type" : "string"
+          },
           "type" : {
             "type" : "string"
           }
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteTemplateTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteTemplateTest.groovy
index cd0f75370a9..4efb3fcef9c 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteTemplateTest.groovy
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteTemplateTest.groovy
@@ -100,26 +100,8 @@ class RouteTemplateTest extends YamlTestSupport {
                             id: "myTemplate"
                             beans:
                               - name: "myProcessor"
-                                type: "groovy"
-                                script: "new ${MyUppercaseProcessor.class.name}()"
-                            from:
-                              uri: "direct:{{directName}}"
-                              steps:
-                                - process:
-                                    ref: "{{myProcessor}}"
-                        - from:
-                            uri: "direct:start"
-                            steps:
-                              - to: "direct:myId"
-                              - to: "mock:result"
-                    """),
-                asResource('script-bean-type', """
-                        - routeTemplate:
-                            id: "myTemplate"
-                            beans:
-                              - name: "myProcessor"
-                                type: "groovy"
-                                bean-type: "org.apache.camel.Processor"
+                                type: "${MyUppercaseProcessor.class.name}"
+                                scriptLanguage: "groovy"
                                 script: "new ${MyUppercaseProcessor.class.name}()"
                             from:
                               uri: "direct:{{directName}}"
@@ -137,7 +119,8 @@ class RouteTemplateTest extends YamlTestSupport {
                             id: "myTemplate"
                             beans:
                               - name: "myProcessor"
-                                type: "groovy"
+                                type: "org.apache.camel.Processor"
+                                scriptLanguage: "groovy"
                                 script: |
                                     new ${MyUppercaseProcessor.class.name}()
                             from:
@@ -339,7 +322,8 @@ class RouteTemplateTest extends YamlTestSupport {
                         id: "myTemplate"
                         beans:
                           - name: "myAgg"
-                            type: "joor"
+                            type: "org.apache.camel.AggregationStrategy"
+                            scriptLanguage: "joor"
                             script: "(e1, e2) -> { return e2.getMessage().getBody(); }"
                         from:
                           uri: "direct:route"
@@ -384,7 +368,8 @@ class RouteTemplateTest extends YamlTestSupport {
                         id: "myTemplate"
                         beans:
                           - name: "myAgg"
-                            type: "groovy"
+                            type: "org.apache.camel.AggregationStrategy"
+                            scriptLanguage: "groovy"
                             script: "class MaxAgg { int agg(int s1, int s2) { return Math.max(s1, s2) }}; new MaxAgg()"
                         from:
                           uri: "direct:route"
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/TemplatedRouteTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/TemplatedRouteTest.groovy
index f8c9fcae06d..5670ac02f93 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/TemplatedRouteTest.groovy
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/TemplatedRouteTest.groovy
@@ -43,7 +43,8 @@ class TemplatedRouteTest extends YamlTestSupport {
                         value: "foo"
                     beans:
                       - name: "myProcessor"
-                        type: "groovy"
+                        type: "${MyUppercaseProcessor.class.name}" 
+                        scriptLanguage: "groovy"
                         script: |
                             new ${MyUppercaseProcessor.class.name}()
                 - templatedRoute:
@@ -54,8 +55,8 @@ class TemplatedRouteTest extends YamlTestSupport {
                         value: "foo2"
                     beans:
                       - name: "myProcessor"
-                        type: "groovy"
-                        beanType: "org.apache.camel.Processor"
+                        type: "org.apache.camel.Processor"
+                        scriptLanguage: "groovy"
                         script: "new ${MyUppercaseProcessor.class.name}()"                 
             """
         withMock('mock:result') {
@@ -100,7 +101,8 @@ class TemplatedRouteTest extends YamlTestSupport {
                         value: "foo"
                     beans:
                       - name: "myProcessor"
-                        type: "groovy"
+                        type: "org.apache.camel.Processor"
+                        scriptLanguage: "groovy"
                         script: |
                             new ${MyUppercaseProcessor.class.name}()
                 - templatedRoute:
@@ -111,8 +113,8 @@ class TemplatedRouteTest extends YamlTestSupport {
                         value: "foo2"
                     beans:
                       - name: "myProcessor"
-                        type: "groovy"
-                        beanType: "org.apache.camel.Processor"
+                        type: "org.apache.camel.Processor"
+                        scriptLanguage: "groovy"
                         script: "new ${MyUppercaseProcessor.class.name}()"                 
             """
         withMock('mock:result') {