Embedding Camel in a Spring application
This recipe will show you how to integrate Camel into a Spring application.
Getting ready
When using Camel within a Spring application, it is necessary to add the following dependencies to the minimal set defined in the Using Camel in a Java application recipe in this chapter:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>${camel-version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-test-spring</artifactId> <version>${camel-version}</version> <scope>test</scope> </dependency>
The ${camel-version}
property is defined once in the Maven POM.
The Java code for this recipe is located in the org.camelcookbook.structuringroutes.simplespring
package. The Spring XML files are located under src/main/resources/META-INF/spring
and prefixed with simplespring
.
How to do it...
In order to embed Camel into a Spring application, perform the following steps:
- In the XML namespace declaration, define the Camel schema alongside any Spring schemas in use:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:camel="http://camel.apache.org/schema/spring" 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">
- The
camelContext
element should be defined once within the Spring configuration, and it should use the Camel Spring namespace. This signifies that everything within it will be considered Camel configuration as opposed to Spring.<camelContext xmlns="http://camel.apache.org/schema/spring"> <!-- routing logic goes here --> </camelContext>
- Routes can then be defined within the
camelContext
element using the XML DSL:<route> <from uri="timer:logMessageTimer?period=1s"/> <to uri="mylogger:insideTheRoute?showHeaders=true"/> <log message="Event triggered by ${property.CamelTimerName} at ${header.CamelTimerFiredTime}"/> </route>
How it works...
Camel was designed to be closely integrated with Spring from its inception. The camelContext
element results in a SpringCamelContext
object being created, initialized with any routes defined within it, and started when the Spring context starts up. The camelContext
element is itself a Spring managed object that can optionally be given an ID and treated like any other bean.
The preceding example shows Camel's XML DSL being used. One of the nice things about the DSL is that an XML schema is used to define it. This means that it is possible for your IDE to provide you with code completion.
It is not mandatory to use the XML DSL with Spring. It is possible to use the Java DSL instead, or alongside routes defined through the XML DSL.
To plug in the route defined in the LogMessageOnTimerEventRouteBuilder
class that we used in the previous recipe, we first instantiate it as a bean:
<!-- package name has been abbreviated --> <bean id="logMessageOnTimerEvent" class="org.camelcookbook.structuringroutes.simple.LogMessageOnTimerEventRouteBuilder"/>
Then we add it to the camelContext
element using the routeBuilder
tag:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <routeBuilder ref="logMessageOnTimerEvent"/> </camelContext>
Multiple routeBuilder
elements can be used within a camelContext
.
There's more...
If you define a number of RouteBuilder
s in the same package, it is possible for Camel to scan that package and instantiate all of the routes that it finds:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <packageScan> <package>org.camelcookbook.structuringroutes</package> </packageScan> </camelContext>
You can add multiple package
elements within the packageScan
element, and also use wildcards to include or exclude RouteBuilder
s by name, using the excludes
and includes
elements.
Spring provides an alternative feature called
component scanning. When enabled, the Spring application context recursively scans a package, and instantiates any class within that is annotated with org.springframework.stereotype.Component
. Any properties annotated with @Autowired
, or the CDI equivalent @Inject
, have their dependencies injected. Camel can be configured to pick up any RouteBuilder
s wired through this process. The RouteBuilder
s must first be marked as components:
@Component public class LogMessageOnTimerEventRouteBuilder extends RouteBuilder { //... };
To enable the wiring, turn on component scanning in Spring:
<component-scan base-package="org.camelcookbook.structuringroutes" xmlns="http://www.springframework.org/schema/context"/>
Then add the appropriate feature to the Camel context to tie it all together:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <component-scan/> </camelContext>