blob: 469a7bfddb83bdca66c68d2e1217c76f803526f4 [file] [log] [blame]
= Xml Io Dsl Component
//TODO there is no .json file for this doc page, so it is not updated automatically by UpdateReadmeMojo.
//Header attributes written by hand.
:doctitle: XML Io Dsl
:artifactid: camel-xml-io-dsl
:description: Camel DSL with XML
:since: 3.9
:supportlevel: Stable
//Manually maintained attributes
:group: DSL
*Since Camel {since}*
The `xml-io-dsl` is the Camel optimized XML DSL with a very fast and low overhead XML parser.
The classic XML DSL was loaded via JAXB that is heavy and overhead.
The JAXB parser is generic and can be used for parsing any XML.
However, the `xml-io-dsl` is a source code generated parser that is Camel specific and can only parse Camel `.xml`
route files (not classic Spring `<beans>` XML files).
If you are using Camel XML DSL then it is recommended using `xml-io-dsl` instead of `xml-jaxb-dsl`.
You can use this in all of Camel's runtime such as Spring Boot, Quarkus, Camel Main.
== Example
The following `my-route.xml` source file:
.my-route.xml
[source,xml]
----
<routes xmlns="http://camel.apache.org/schema/xml-io">
<route>
<from uri="timer:tick"/>
<setBody>
<constant>Hello Camel!</constant>
</setBody>
<to uri="log:info"/>
</route>
</routes>
----
TIP: You can omit the `xmlns` namespace. And if there is only a single route, you can use `<route>` as the root XML tag.
Can then be loaded and run with Camel CLI.
.Running with Camel CLI
[source,bash]
----
camel run my-route.xml
----
*Since Camel 4.0.0*
It is now possible with `xml-io-dsl` to declare some beans to be bound to xref:manual::registry.adoc[Camel Registry] in similar way as with xref:yaml-dsl.adoc[YAML DSL]. Beans may be declared in XML and have their properties (also nested) defined. For example:
[source,xml]
----
<camel>
<bean name="beanFromProps" type="com.acme.MyBean">
<properties>
<property key="field1" value="f1_p" />
<property key="field2" value="f2_p" />
<property key="nested.field1" value="nf1_p" />
<property key="nested.field2" value="nf2_p" />
</properties>
</bean>
</camel>
----
=== Loading Spring XML files with embedded beans
**Deprecated**
While keeping all the benefits of fast XML parser used by `xml-io-dsl`, Camel can also process XML elements declared in other XML namespaces and process them separately. With this mechanism it is possible to include XML elements using Spring's `http://www.springframework.org/schema/beans` namespace.
This brings the flexibility of Spring Beans into xref:components:others:main.adoc[Camel Main] without actually running any Spring Application Context (or Spring Boot). When elements from Spring namespace are found, they are used to populate and configure an instance of `org.springframework.beans.factory.support.DefaultListableBeanFactory` and leverage Spring dependency injection to wire the beans together. These beans are then exposed through normal xref:manual::registry.adoc[Camel Registry] and may be used by Camel routes.
Here's an example `camel.xml` file, which defines both the routes and beans used (referred to) by the route definition:
.camel.xml
[source,xml]
----
<camel>
<beans xmlns="http://www.springframework.org/schema/beans">
<bean id="messageString" class="java.lang.String">
<constructor-arg index="0" value="Hello"/>
</bean>
<bean id="greeter" class="org.apache.camel.main.app.Greeter">
<description>Spring Bean</description>
<property name="message">
<bean class="org.apache.camel.main.app.GreeterMessage">
<property name="msg" ref="messageString"/>
</bean>
</property>
</bean>
</beans>
<route id="my-route">
<from uri="direct:start"/>
<bean ref="greeter"/>
<to uri="mock:finish"/>
</route>
</camel>
----
A `my-route` route is referring to `greeter` bean which is defined using Spring `<bean>` element.
More examples can be found in xref:manual:ROOT:camel-jbang.adoc#_using_spring_beans_in_camel_xml_dsl[Camel JBang] page.
=== Using bean with constructors
When beans must be created with constructor arguments, then this is made easier in Camel 4.1 onwards.
For example as shown below:
[source,xml]
----
<camel>
<bean name="beanFromProps" type="com.acme.MyBean">
<constructors>
<constructor index="0" value="true"/>
<constructor index="1" value="Hello World"/>
</constructors>
<!-- and you can still have properties -->
<properties>
<property key="field1" value="f1_p" />
<property key="field2" value="f2_p" />
<property key="nested.field1" value="nf1_p" />
<property key="nested.field2" value="nf2_p" />
</properties>
</bean>
</camel>
----
If you use Camel 4.0, then constructor arguments must be defined in the `type` attribute:
[source,xml]
----
<bean name="beanFromProps" type="com.acme.MyBean(true, 'Hello World')">
<properties>
<property key="field1" value="f1_p" />
<property key="field2" value="f2_p" />
<property key="nested.field1" value="nf1_p" />
<property key="nested.field2" value="nf2_p" />
</properties>
</bean>
----
=== Creating beans from factory method
A bean can also be created from a factory method (public static) as shown below:
[source,xml]
----
<bean name="myBean" type="com.acme.MyBean" factoryMethod="createMyBean">
<constructors>
<constructor index="0" value="true"/>
<constructor index="1" value="Hello World"/>
</constructors>
</bean>
----
When using `factoryMethod` then the arguments to this method is taken from `constructors`.
So in the example above, this means that class `com.acme.MyBean` should be as follows:
[source,java]
----
public class MyBean {
public static MyBean createMyBean(boolean important, String message) {
MyBean answer = ...
// create and configure the bean
return answer;
}
}
----
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:
[source,xml]
----
<bean name="myBean" type="com.acme.MyBean"
factoryBean="com.acme.MyHelper" factoryMethod="createMyBean">
<constructors>
<constructor index="0" value="true"/>
<constructor index="1" value="Hello World"/>
</constructors>
</bean>
----
TIP: `factoryBean` can also refer to an existing bean by bean id instead of FQN classname.
When using `factoryBean` and `factoryMethod` then the arguments to this method is taken from `constructors`.
So in the example above, this means that class `com.acme.MyHelper` should be as follows:
[source,java]
----
public class MyHelper {
public static MyBean createMyBean(boolean important, String message) {
MyBean answer = ...
// create and configure the bean
return answer;
}
}
----
NOTE: The factory method must be `public static`.
=== 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.
This gives flexibility to use a bit of programming to create and configure the bean.
[source,xml]
----
<bean name="myBean" type="com.acme.MyBean" scriptLanguage="groovy">
<script>
// some groovy script here to create the bean
bean = ...
...
return bean
</script>
</bean>
----
NOTE: When using `script` then constructors and factory bean/method is not in use
=== Using init and destroy methods on beans
Sometimes beans need to do some initialization and cleanup work before a bean is ready to be used.
For this you can use `initMethod` and `destroyMethod` that Camel triggers accordingly.
Those methods must be public void and have no arguments, as shown below:
[source,java]
----
public class MyBean {
public void initMe() {
// do init work here
}
public void destroyMe() {
// do cleanup work here
}
}
----
You then have to declare those methods in XML DSL as follows:
[source,xml]
----
<bean name="myBean" type="com.acme.MyBean"
initMethod="initMe" destroyMethod="destroyMe">
<constructors>
<constructor index="0" value="true"/>
<constructor index="1" value="Hello World"/>
</constructors>
</bean>
----
The init and destroy methods are optional, so a bean does not have to have both,
for example you may only have a destroy methods.
== See Also
See xref:manual:ROOT:dsl.adoc[DSL]