...
- Adding Camel schema
- Configure Routes in two ways:
- Using Java Code
- Using Spring XML
Adding Camel Schema
For Camel 1.x you need to use the following namespace:
Code Block |
---|
http://activemq.apache.org/camel/schema/spring |
with the following schema location:
Code Block |
---|
http://activemq.apache.org/camel/schema/spring/camel-spring.xsd |
You need to add Camel to the schemaLocation
declaration
Code Block |
---|
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd |
So the XML file looks like this:
Code Block | ||
---|---|---|
| ||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd "> |
Using camel:
Namespace
Or you can refer to the camel XSD in the XML declaration:
Code Block |
---|
xmlns:camel="http://camel.apache.org/schema/spring" |
... so the declaration is:
Code Block | ||
---|---|---|
| ||
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
camel:
namespace prefix, and you can omit the inline namespace declaration:
Code Block | ||
---|---|---|
| ||
<camel:camelContext id="camel5">
<camel:package>org.apache.camel.spring.example</camel:package>
</camel:camelContext>
|
Advanced Configuration Using Spring
...
You can use Java Code to define your RouteBuilder implementations. These can be defined as beans in spring and then referenced in your camel context e.g.
Code Block | ||
---|---|---|
| ||
<camelContext id="camel5" xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="myBuilder" />
</camelContext>
<bean id="myBuilder" class="org.apache.camel.spring.example.test1.MyRouteBuilder"/> |
Using <package>
Camel also provides a powerful feature that allows for the automatic discovery and initialization of routes in given packages. This is configured by adding tags to the camel context in your spring context definition, specifying the packages to be recursively searched for RouteBuilder implementations. To use this feature in 1.X
, requires a <package></package>
tag specifying a comma separated list of packages that should be searched e.g.
...
camelContextRouteBuilderRef.xml
Code Block | ||
---|---|---|
| ||
<camel:camelContext id="camel5"> <camel:package>org.apache.camel.spring. |
...
example</camel:package> </camel:camelContext> |
Use caution when specifying the package name as org.apache.camel
or a sub package of this. This causes Camel to search in its own packages for your routes which could cause problems.
Will ignore already instantiated classes
The <package>
and <packageScan>
will skip any classes which has already been created by Spring etc. So if you define a route builder as a spring bean tag then that class will be skipped. You can include those beans using <routeBuilder ref="theBeanId"/>
or the <contextScan>
feature.
Using <packageScan>
In Camel 2.0 this has been extended to allow selective inclusion and exclusion of discovered route classes using Ant like path matching. In spring this is specified by adding a <packageScan/>
tag. The tag must contain one or more package
elements (similar to 1.x
), and optionally one or more includes
or excludes
elements specifying patterns to be applied to the fully qualified names of the discovered classes. e.g.,
Code Block | ||
---|---|---|
| ||
<camelContext xmlns="http://camel.apache.org/schema/spring"> <packageScan> <package>org.example.routes</package> <excludes>**.*Excluded*</excludes> <includes>**.*</includes> </packageScan> </camelContext> |
Exclude patterns are applied before the include patterns. If no include or exclude patterns are defined then all the Route classes discovered in the packages will be returned.
...
Under the covers, this is using Spring's AntPatternMatcher implementation, which matches as follows
? matches one character * matches zero or more characters ** matches zero or more segments of a fully qualified name
For example:
**.*Excluded*
would match org.simple.Excluded
, org.apache.camel.SomeExcludedRoute
or org.example.RouteWhichIsExcluded
.
...
You can allow Camel to scan the container context, e.g. the Spring ApplicationContext
for route builder instances. This allow you to use the Spring <component-scan>
feature and have Camel pickup any RouteBuilder
instances which was created by Spring in its scan process.
Code Block | ||
---|---|---|
| ||
<!-- enable Spring @Component scan -->
<context:component-scan base-package="org.apache.camel.spring.issues.contextscan"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<!-- and then let Camel use those @Component scanned route builders -->
<contextScan/>
</camelContext> |
This allows you to just annotate your routes using the Spring @Component
and have those routes included by Camel:
Code Block | ||
---|---|---|
| ||
@Component public class MyRoute extends SpringRouteBuilder { @Override public void configure() throws Exception { from("direct:start") .to("mock:result"); } } |
You can also use the ANT style for inclusion and exclusion, as mentioned above in the <packageScan>
documentation.
how do i import routes from other xml files
Test Time Exclusion.
At test time it is often desirable to be able to selectively exclude matching routes from being initialized that are not applicable or useful to the test scenario. For instance you might a spring context file routes-context.xml
and three Route builders RouteA
, RouteB
and RouteC
in the org.example.routes
package. The packageScan
definition would discover all three of these routes and initialize them.
Say RouteC
is not applicable to our test scenario and generates a lot of noise during test. It would be nice to be able to exclude this route from this specific test. The SpringTestSupport
class has been modified to allow this. It provides two methods (excludedRoute
and excludedRoutes
) that may be overridden to exclude a single class or an array of classes.
Code Block | ||
---|---|---|
| ||
@Component public class MyRoute extends SpringRouteBuilder { @Override public void configure() throws Exception { from("direct:start") .to("mock:result"); } } |
javapublic class RouteAandRouteBOnlyTest extends SpringTestSupport { @Override protected Class excludeRoute() { return RouteC.class; } }
In order to hook into the camelContext
initialization by spring to exclude the MyExcludedRouteBuilder.class
we need to intercept the spring context creation. When overriding createApplicationContext
to create the spring context, we call the getRouteExcludingApplicationContext()
method to provide a special parent spring context that takes care of the exclusion.
Code Block | ||
---|---|---|
| ||
@Override protected AbstractXmlApplicationContext createApplicationContext() { return new ClassPathXmlApplicationContext( new String[] {"routes-context.xml"}, getRouteExcludingApplicationContext()); } |
will now be excluded from initialization. Similarly, in another test that is testing only
RouteCRouteC
, we could exclude RouteB
and RouteA
by overriding:
Code Block | ||
---|---|---|
| ||
@Override protected Class[] excludeRoutes() { return new Class[]{RouteA.class, RouteB.class}; } |
Using Spring XML
You can use Spring 2.0 XML configuration to specify your Xml Configuration for Routes such as in the following example.
Code Block | ||
---|---|---|
| ||
<camelContext id="camel-A" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="seda:start"/>
<to uri="mock:result"/>
</route>
</camelContext> |
Configuring Components and Endpoints
You can configure your Component or Endpoint instances in your Spring XML as follows in this example.
Code Block | ||
---|---|---|
| ||
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<jmxAgent id="agent" disabled="true"/>
</camelContext>
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="vm://localhost?broker.persistent=false&broker.useJmx=false"/>
</bean>
</property>
</bean> |
activemq
in the above example), then you can refer to the component using activemq:[queue:|topic:]destinationName
. This works by the SpringCamelContext
lazily fetching components from the spring context for the scheme name you use for Endpoint URIs.
...
Available as of Camel 2.17.1
Code Block | ||
---|---|---|
| ||
<bean id="repo" class="org.apache.camel.spring.processor.idempotent.SpringCacheIdempotentRepository"> <constructor-arg> <bean class="org.springframework.cache.guava.GuavaCacheManager"/> </constructor-arg> <constructor-arg value="idempotent"/> </bean> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route id="idempotent-cache"> <from uri="direct:start" /> <idempotentConsumer messageIdRepositoryRef="repo" skipDuplicate="true"> <header>MessageId</header> <to uri="log:org.apache.camel.spring.processor.idempotent?level=INFO&showAll=true&multiline=true" /> <to uri="mock:result"/> </idempotentConsumer> </route> </camelContext> |
...
CamelContextAware
If you want to be injected with the CamelContext in your POJO just implement the CamelContextAware interface; then when Spring creates your POJO the CamelContext
will be injected into your POJO. Also see the Bean Integration for further injections.
...