Camel Guice
As of 1.5 we now have support for Google Guice as a dependency injection framework.
To use it just be dependent on camel-guice.jar which also depends on the following jars
Dependency Injecting Camel with Guice
The GuiceCamelContext is designed to work nicely inside Guice. You then need to bind it using some Guice Module.
The camel-guice library comes with a number of reusable Guice Modules you can use if you wish - or you can bind the GuiceCamelContext yourself in your own module.
- CamelModule is the base module which binds the GuiceCamelContext but leaves it up you to bind the RouteBuilder instances
- CamelModuleWithRouteTypes extends CamelModule so that in the constructor of the module you specify the RouteBuilder classes or instances to use
- CamelModuleWithMatchingRoutes extends CamelModule so that all bound RouteBuilder instances will be injected into the CamelContext or you can supply an optional Matcher to find RouteBuilder instances matching some kind of predicate.
So you can specify the exact RouteBuilder instances you want
Injector injector = Guice.createInjector(new CamelModuleWithRouteTypes(MyRouteBuilder.class, AnotherRouteBuilder.class)); // if required you can lookup the CamelContext CamelContext camelContext = injector.getInstance(CamelContext.class);
Or inject them all
Injector injector = Guice.createInjector(new CamelModuleWithRouteTypes()); // if required you can lookup the CamelContext CamelContext camelContext = injector.getInstance(CamelContext.class);
You can then use Guice in the usual way to inject the route instances or any other dependent objects.
Configuring Component, Endpoint or RouteBuilder instances
You can use Guice to dependency inject whatever objects you need to create, be it an Endpoint, Component, RouteBuilder or arbitrary bean used within a route.
The easiest way to do this is to create your own Guice Module class which extends one of the above module classes and add a provider method for each object you wish to create. A provider method is annotated with @Provides as follows
public class MyModule extends CamelModuleWithMatchingRoutes { @Provides @JndiBind("jms") JmsComponent jms(@Named("activemq.brokerURL") String brokerUrl) { return JmsComponent.jmsComponent(new ActiveMQConnectionFactory(brokerUrl)); } }
You can optionally annotate the method with @JndiBind to bind the object to JNDI at some name if the object is a component, endpoint or bean you wish to refer to by name in your routes.
You can inject any environment specific properties (such as URLs, machine names, usernames/passwords and so forth) from the jndi.properties file easily using the @Named annotation as shown above. This allows most of your configuration to be in Java code which is typesafe and easily refactorable - then leaving some properties to be environment specific (the jndi.properties file) which you can then change based on development, testing, production etc.
Creating multiple RouteBuilder instances per type
It is sometimes useful to create multiple instances of a particular RouteBuilder with different configurations.
To do this just create multiple provider methods for each configuration; or create a single provider method that returns a collection of RouteBuilder instances.
For example
import org.apache.camel.guice.CamelModuleWithMatchingRoutes; import public class MyModule extends CamelModuleWithMatchingRoutes { @Provides @JndiBind("foo") Collection<RouteBuilder> foo(@Named("fooUrl") String fooUrl) { return Lists.newArrayList(new MyRouteBuilder(fooUrl), new MyRouteBuilder("activemq:CheeseQueue")); } }
Examples
There are a number of Examples you can look at to see Guice and Camel being used such as