Chapter 5. XML IO DSL
The xml-io-dsl
is the Camel optimized XML DSL with a very fast and low overhead XML parser. It is a source code generated parser that is Camel specific and can only parse Camel .xml
route files (not classic Spring <beans>
XML files).
We recommend that you use xml-io-dsl
instead of xml-jaxb-dsl
for Camel XML DSL. It works with all Camel runtimes.
When you are using XML IO DSL, the camel-spring-boot
application will by default look for xml files in src/main/resources/camel/*.xml
.
You can configure this behavior by providing a different path in the camel.springboot.routes-include-pattern
property:
camel.springboot.routes-include-pattern=/path/to/*.xml
5.1. Example
The following my-route.xml
source file can be loaded and run with Camel CLI or Camel K:
my-route.xml
<routes xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="timer:tick"/> <setBody> <constant>Hello Camel K!</constant> </setBody> <to uri="log:info"/> </route> </routes>
You can omit the xmlns
namespace.
If there is only a single route, you can use <route>
as the root XML tag instead of <routes>
.
Running with Camel K
kamel run my-route.xml
Running with Camel CLI
camel run my-route.xml
You can use xml-io-dsl
to declare some beans to be bound to the Camel Registry.
You can declare and Beans define their properties (including nested
properties) in XML. For example:
Bean declaration and definition
<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>
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 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 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
<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 on the Apache Camel JBang page.
5.2. Using beans with constructors
When you want to create beans with constructor arguments, from Camel 4.1 onwards you can add them as XML tags. For example:
Camel 4.1+: Beans with constructor
tags
<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, you must put then constructor arguments in the type
attribute:
Camel 4.0: Beans with constructor
arguments in the type
attribute
<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>
5.3. Creating beans from factory method
A bean can also be created from a public static
factory method:
Factory method 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 you use a factoryMethod
, you must provide constructor
tags for the arguments.
For example, this means that the class com.acme.MyBean
should be as follows:
Factory method
public class MyBean { public static MyBean createMyBean(boolean important, String message) { MyBean answer = ... // create and configure the bean return answer; } }
You must make the factory method public static
in the created class.
5.4. Creating beans from builder classes
You can create a bean created from another builder class as shown below:
Builder 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>
You must make the builder class public
with a no-arg default constructor.
You can then use the builder class to create the actual bean by using fluent builder style configuration.
Set the properties on the builder class, and create the bean by invoking the builderMethod
at the end.
You invocate this method via Java reflection.
5.5. Creating beans from factory bean
You can create a bean from a factory bean as shown below:
Factory 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>
You can also use factoryBean
to refer to an existing bean by bean id instead of the FQN classname.
When you use a factoryBean
the, you must provide arguments as constructor
tags.
For example, the class com.acme.MyHelper
should be as follows:
Factory bean
public class MyHelper { public static MyBean createMyBean(boolean important, String message) { MyBean answer = ... // create and configure the bean return answer; } }
You must make the factory method public static
.
5.6. Creating beans using script language
If you have advanced use-cases, you can inline a script language, such as groovy, java, javascript, and so on, to create the bean.
With scripting, you can be more flexible and use a bit of programming to create and configure the bean:
Scripting
<bean name="myBean" type="com.acme.MyBean" scriptLanguage="groovy"> <script> // some groovy script here to create the bean bean = ... ... return bean </script> </bean>
When you use script
, the constructors, factory bean, and factory method are not used.
5.7. Using init
and destroy
methods on beans
If you need to do initialization and cleanup work before you use a bean, you can use the initMethod
and destroyMethod
which are triggered as appropriate by Camel.
Those methods must be public void
and have no arguments, as shown below:
Initialization and cleanup methods
public class MyBean { public void initMe() { // do init work here } public void destroyMe() { // do cleanup work here } }
You also have to declare those methods in the XML DSL as follows:
Initialization and cleanup 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>
Both initMethod
and destroyMethod
are optional, so a bean does not have to have both.
5.8. REST and routes in the same XML IO DSL file
You can have both REST and routes in the same DSL file:
REST and routes in the same XML IO DSL file
<camel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://camel.apache.org/schema/spring" xsi:schemaLocation=" http://camel.apache.org/schema/spring https://camel.apache.org/schema/spring/camel-spring.xsd"> <rest id="rest"> <post id="post" path="start"> <to uri="direct:start"/> </post> </rest> <route> <from uri="direct:start"/> <to uri="amqp:queue:Test.Broker.StreamMessage?jmsMessageType=Stream&disableReplyTo=true"/> </route> </camel>