What is Camel auto-configuration for Spring Boot?
Spring Boot Camel component provides auto-configuration for the Apache Camel. Our opinionated auto-configuration of the Camel context auto-detects Camel routes available in the Spring context and registers the key Camel utilities (like producer template, consumer template and the type converter) as beans.
How to enable Camel auto-configuration in my Spring Boot application?
Just drop camel-spring-boot jar into your classpath:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring-boot</artifactId> <version>${camel.version}</version> <!-- use the same version as your Camel core version --> </dependency>
camel-spring-boot jar comes with the spring.factories file, so as soon as you add that dependency into your classpath, Spring Boot will automatically auto-configure the Camel for you. Yay! That was fast ;) .
Auto-configured Camel context
The most important piece of functionality provided by the Camel auto-configuration is the CamelContext instance. Camel auto-configuration creates SpringCamelContext for your and take care of the proper initialization and shutdown of that context. Created Camel context is also registered in the Spring application context (under camelContext bean name), so you can access it just as the any other Spring bean.
@Configuration public class MyAppConfig { @Autowired CamelContext camelContext; @Bean MyService myService() { return new DefaultMyService(camelContext); } }Keep in mind however that usually you don't really have to inject CamelContext directly into your application, as you can use the feature called...
Auto-detecting Camel routes
Camel auto-configuration collects all the RoutesBuilder instances from the Spring context and automatically injects them into the provided CamelContext. It means that creating new Camel route with the Spring Boot starter is as simple as adding the @Component annotated class into your classpath...
@Component public class MyRouter extends RouteBuilder { @Override public void configure() throws Exception { from("jms:invoices").to("file:/invoices"); } }...or creating a new route RoutesBuilder bean in your @Configuration class:
@Configuration public class MyRouterConfiguration { @Bean RoutesBuilder myRouter() { return new RouteBuilder() { @Override public void configure() throws Exception { from("jms:invoices").to("file:/invoices"); } }; } }
Ideally, you should not wire routes into the CamelContext by yourself. It is simpler just to add them to the classpath and let the Spring Boot to wire them for you.
Camel properties
Spring Boot auto-configuration automatically connect Spring Boot external configuration (like properties placeholders, OS environment variables or system properties) with the Camel properties support. It basically means that any property defined in application.properties file...
route.from = jms:invoices...or set via the system property...
java -Droute.to=jms:processed.invoices -jar mySpringApp.jar...can be used as the placeholder in the Camel route:
@Component public class MyRouter extends RouteBuilder { @Override public void configure() throws Exception { from("{{route.from}}").to("{{route.to}}"); } }
Basically any property available for the Spring property resolver can be resolved by the Camel properties component as well.
Customizing Camel context configuration
If you would like to perform some operations on CamelContext bean created by Camel auto-configuration, register CamelContextConfiguration instance in your Spring context:
@Configuration public class MyAppConfig { ... @Bean CamelContextConfiguration contextConfiguration() { return new CamelContextConfiguration() { @Override void beforeStart(CamelContext context) { // your custom configuration goes here } }; } }Method CamelContextConfiguration#beforeStart(CamelContext) will be call just before the Spring starts the auto-configured CamelContext.
Auto-configured consumer and producer templates
Camel auto-configuration provides a pre-configured ConsumerTemplate and ProducerTemplate instances. You can simply inject them into your Spring-managed beans:
@Component public class InvoiceProcessor { @Autowired private ProducerTemplate producerTemplate; @Autowired private ConsumerTemplate consumerTemplate; public void processNextInvoice() { Invoice invoice = consumerTemplate.receiveBody("jms:invoices", Invoice.class); ... producerTemplate.sendBody("netty-http:http://invoicing.com/received/" + invoice.id()); } }In the example above I read a message from the JMS queue, convert it into the domain class called Invoice and finally use HTTP call to send confirmation to some external system that I processed the invoice. No Camel routes here, only consumer/producer templates.
By default consumer and producer templates come with the endpoint cache sizes equal to 1000. You can change that values via the following Spring properties:
camel.springboot.consumerTemplateCacheSize = 100 camel.springboot.producerTemplateCacheSize = 200
Auto-configured TypeConverter
Camel auto-configuration registers TypeConverter instance named typeConverter in the Spring context.
@Component public class InvoiceProcessor { @Autowired private TypeConverter typeConverter; public long parseInvoiceValue(Invoice invoice) { String invoiceValue = invoice.grossValue(); return typeConverter.convertTo(Long.class, invoiceValue); } }As you can see the type converter is pretty handy when performing conversions between two data types, so it is very useful to have it available in your Spring components.
What's next?
There are still many features I'd like to see in Camel Spring Boot. Just to mention some of them:
- Test helpers API. We don't really need a full-blown testing API, like for the old Camel or Camel Spring. Spring Boot testing API enhanced by the Camel auto-configuration is flexible enough to handle all the most important testing scenarios (like loading routes, overriding the configuration and so forth) without any additional Camel-specific testing utilities. However having a base class with some extra helper methods to avoid testing-code boilerplate will be always appreciated.
- Registering custom converters. I'd like to make it really easy to register new Camel type converters. As simple as adding new converter bean to the Spring context.
- Bridge between Spring and Camel converters. Spring comes with its own types converter API. I will be nice to bridge Spring converters to Camel (and reversely) so end-users could benefit from the maximum number of converters available for them.
- Making sure that Camel components work nicely with Spring Boot. That would require creating some pull requests to Spring Boot upstream and changes in the code of some components to be sure that those can properly pick up the beans pre-configured by Spring Boot. For example I would like to be sure that camel-jpa component plays nicely with the default Hibernate configuration provided by the Spring Boot JPA auto-configuration.
Give it a shot!
Just try to use the new Spring Boot support for Camel and let me know what do you think of it. Do you feel it lacks some functionality? Something is not working as it should? Our documentation sucks? Feel free to ping me.