| [[SpringSupport-SpringSupport]] |
| = Spring Support |
| :page-source: components/camel-spring/src/main/docs/spring.adoc |
| |
| Apache Camel is designed to work nicely with the |
| http://www.springframework.org/[Spring Framework] in a number of ways. |
| |
| * Camel uses Spring Transactions as the default transaction handling in |
| components like xref:jms-component.adoc[JMS] and xref:jms-component.adoc[JPA] |
| * Camel works with Spring 2 XML processing with the |
| Xml Configuration |
| * Camel Spring XML Schema's is defined at xref:manual::xml-reference.adoc[Xml |
| Reference] |
| * Camel provides powerful Bean Integration |
| with any bean defined in a Spring ApplicationContext |
| * Camel integrates with various Spring helper classes; such as providing |
| Type Converter support for Spring Resources |
| etc |
| * Allows Spring to dependency inject Component |
| instances or the CamelContext instance itself |
| and auto-expose Spring beans as components and endpoints. |
| * Allows you to reuse the Spring Testing |
| framework to simplify your unit and integration testing using |
| xref:manual::enterprise-integration-patterns.adoc[Enterprise Integration |
| Patterns] and Camel's powerful xref:mock-component.adoc[Mock] and |
| xref:test.adoc[Test] endpoints |
| Camel supports Spring Boot using the `camel-spring-boot` component. |
| |
| == Using Spring to configure the CamelContext |
| |
| You can configure a CamelContext inside any spring.xml using the |
| http://camel.apache.org/maven/current/camel-spring/apidocs/org/apache/camel/spring/CamelContextFactoryBean.html[CamelContextFactoryBean]. |
| This will automatically start the |
| CamelContext along with any referenced |
| Routes along any referenced |
| Component and Endpoint |
| instances. |
| |
| * Adding Camel schema |
| * Configure Routes in two ways: |
| ** Using Java Code |
| ** Using Spring XML |
| |
| == Adding Camel Schema |
| |
| You need to add Camel to the `schemaLocation` declaration |
| |
| [source,java] |
| -------------------------------------------------------------------------------------------- |
| http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd |
| -------------------------------------------------------------------------------------------- |
| |
| So the XML file looks like this: |
| |
| [source,xml] |
| ------------------------------------------------------------------------------------------------------------------ |
| <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 camel XSD in the XML declaration: |
| |
| [source,java] |
| --------------------------------------------------- |
| xmlns:camel="http://camel.apache.org/schema/spring" |
| --------------------------------------------------- |
| |
| ... so the declaration is: |
| |
| [source,xml] |
| ------------------------------------------------------------------------------------------------------------------ |
| <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"> |
| ------------------------------------------------------------------------------------------------------------------ |
| |
| ... and then use the camel: namespace prefix, and you can omit the |
| inline namespace declaration: |
| |
| [source,xml] |
| -------------------------------------------------------------------------------------------- |
| <camel:camelContext id="camel5"> |
| <camel:package>org.apache.camel.spring.example</camel:package> |
| </camel:camelContext> |
| -------------------------------------------------------------------------------------------- |
| |
| === Advanced configuration using Spring |
| |
| See more details at |
| xref:manual::advanced-configuration-of-camelcontext-using-spring.adoc[Advanced |
| configuration of CamelContext using Spring] |
| |
| $### Using Java Code |
| |
| 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. |
| |
| === 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. |
| |
| [source,xml] |
| ---------------------------------------------------------------- |
| <camelContext xmlns="http://camel.apache.org/schema/spring"> |
| <package>org.apache.camel.spring.config.scan.route</package> |
| </camelContext> |
| ---------------------------------------------------------------- |
| |
| |
| WARNING: 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. |
| |
| |
| [NOTE] |
| ==== |
| *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> |
| |
| The component allows 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, 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. |
| |
| [source,xml] |
| -------------------------------------------------------------- |
| <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. |
| |
| In the above example, camel will scan all the 'org.example.routes' |
| package and any subpackages for RouteBuilder classes. Say the scan finds |
| two RouteBuilders, one in org.example.routes called 'MyRoute" and |
| another 'MyExcludedRoute' in a subpackage 'excluded'. The fully |
| qualified names of each of the classes are extracted |
| (org.example.routes.MyRoute, |
| org.example.routes.excluded.MyExcludedRoute) and the include and exclude |
| patterns are applied. |
| |
| The exclude pattern **.*Excluded* is going to match the fqcn |
| 'org.example.routes.excluded.MyExcludedRoute' and veto camel from |
| initializing it. |
| |
| Under the covers, this is using Spring's |
| http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/util/AntPathMatcher.html[AntPatternMatcher] |
| implementation, which matches as follows |
| |
| [source,java] |
| ---------------------------------------------------------- |
| ? 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 |
| |
| **.??cluded* would match org.simple.IncludedRoute, org.simple.Excluded |
| but not match org.simple.PrecludedRoute |
| |
| === Using contextScan |
| |
| *Available as of Camel 2.4* |
| |
| 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. |
| |
| This allows you to just annotate your routes using the Spring |
| `@Component` and have those routes included by Camel |
| |
| [source,java] |
| ------------------------------------------------- |
| @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 |
| |
| *Available as of Camel 2.3* |
| |
| When defining routes in Camel using xref:manual::xml-configuration.adoc[Xml |
| Configuration] you may want to define some routes in other XML files. |
| For example you may have many routes and it may help to maintain the |
| application if some of the routes are in separate XML files. You may |
| also want to store common and reusable routes in other XML files, which |
| you can simply import when needed. |
| |
| It is possible to define routes outside |
| `<camelContext/>` which you do in a new `<routeContext/>` tag. |
| |
| *Notice:* When you use <routeContext> then they are separated, and |
| cannot reuse existing <onException>, <intercept>, <dataFormats> and |
| similar cross cutting functionality defined in the <camelContext>. In |
| other words the <routeContext> is currently isolated. |
| |
| For example we could have a file named `myCoolRoutes.xml` which contains |
| a couple of routes as shown: |
| |
| *myCoolRoutes.xml* |
| |
| Then in your XML file which contains the CamelContext you can use Spring |
| to import the `myCoolRoute.xml` file. + |
| And then inside `<camelContext/>` you can refer to the |
| `<routeContext/>` by its id as shown below: |
| |
| Also notice that you can mix and match, having routes inside |
| CamelContext and also externalized in RouteContext. |
| |
| You can have as many `<routeContextRef/>` as you like. |
| |
| *Reusable routes* |
| |
| The routes defined in `<routeContext/>` can be reused by multiple |
| `<camelContext/>`. However its only the definition which is reused. At |
| runtime each CamelContext will create its own instance of the route |
| based on the definition. |
| |
| === Test time exclusion. |
| |
| At test time it is often desirable to be able to selectively exclude |
| matching routes from being initalized 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. |
| |
| [source,java] |
| ---------------------------------------------------------------- |
| public 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. |
| |
| [source,java] |
| -------------------------------------------------------------------------------------------------------------------------- |
| @Override |
| protected AbstractXmlApplicationContext createApplicationContext() { |
| return new ClassPathXmlApplicationContext(new String[] {"routes-context.xml"}, getRouteExcludingApplicationContext()); |
| } |
| -------------------------------------------------------------------------------------------------------------------------- |
| |
| RouteC will now be excluded from initialization. Similarly, in another |
| test that is testing only RouteC, we could exclude RouteB and RouteA by |
| overriding |
| |
| [source,java] |
| --------------------------------------------------- |
| @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 |
| http://svn.apache.org/repos/asf/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/routingUsingCamelContextFactory.xml[example]. |
| |
| == Configuring Components and Endpoints |
| |
| You can configure your Component or |
| Endpoint instances in your Spring |
| XML as follows in |
| http://svn.apache.org/repos/asf/camel/trunk/components/camel-jms/src/test/resources/org/apache/camel/component/jms/jmsRouteUsingSpring.xml[this |
| example]. |
| |
| Which allows you to configure a component using some name (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. |
| |
| For more detail see xref:manual::faq/how-do-i-configure-endpoints.adoc[Configuring |
| Endpoints and Components]. |
| |
| == CamelContextAware |
| |
| If you want to be injected with the CamelContext |
| in your POJO just implement the |
| http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/CamelContextAware.html[CamelContextAware |
| interface]; then when Spring creates your POJO the CamelContext will be |
| injected into your POJO. Also see the xref:manual::bean-integration.adoc[Bean |
| Integration] for further injections. |
| |
| == Integration Testing |
| |
| To avoid a hung route when testing using Spring Transactions see the |
| note about Spring Integration Testing |
| under Transactional Client. |
| |