The Apache Camel framework offers powerful mechanisms to determine which method of your beans to invoke. These are described here in the Camel documentation: http://camel.apache.org/bean-binding.html.
In practice, you have your beans defined with spring and declare their invocation in the Camel route definition either with „beanRef“:
- .beanRef("orderService", "doSomething")
- .to("bean:orderService?method=doSomething")
- Your IDE cannot find the usages of the method invocation of method „doSomething“
- Your IDE cannot assist you during refactorings, e.g. when renaming the method or changing the signature
- Neither your IDE nor the compiler can complain about typos in method names. You will find typos during runtime, not during compile-time.
Replacing the calls with process() is no solution, because you still want the Camel-comfort of the powerful bean-binding.
Using class BeanRef
To use strongly typed invocations in your camel route definitions, that avoid the disadvantages, you can use the utility class BeanRef, with a little more verbose syntax:
- // ...
- from("activemq:orders").to(doSomething()).to("file:confirm.txt")
- // ...
- return new BeanRef<OrderService>(OrderService.class) {
- protected void call() {
- bean.doSomething(null);
- }
- }.uri();
- }
- from("activemq:orders").to("bean:orderService?method=doSomething").to("file:confirm.txt")
It does not matter, which parameter values you are using to invoke „doSomething“, but you need to pass the parameters of the required time, so that the compiler is satisfied. The real method of your bean will not be invoked with this parameter!
When your route calls more myOrderBookService than one method on the service bean, you can call the methods inside call() in their adequate sequence:
- from("activemq:orders").to(new BeanRef<OrderService>(OrderService.class) {
- protected void call() {
- bean.validate(bean.parse(null));
- bean.doSomething(null);
- }
- }.uris()).to(„file:confirm.txt“)
- from("activemq:orders").to(
- "bean:orderService?method=parse",
- "bean:orderService?method=validate",
- "bean:orderService?method=doSomething").to("file:confirm.txt")
- return new BeanRef<SmartWebService>(
- SmartWebService.class, "myOrderBookService"){
- protected void call() {
- bean.doSomething (null);
- }
- }.uri();
- }
This produces the URI:
- "bean:myOrderBookService?method=doSomething"
How does it work?
During definition of the camel route, the call() method of the BeanRef-instance will be invoked with a proxy, that implements the interface of your service bean. The proxy just collects the method invocations and the uri()/uris() methods return the URI-strings of all method invocations.
This is he whole source of class BeanRef:
- package de.viaboxx.camel;
- import java.lang.reflect.*;
- import java.util.*;
- public abstract class BeanRef {
- private final Class beanType;
- protected T bean;
- public BeanRef(Class beanType) {
- this.beanType = beanType;
- this.beanName = uncapitalize(beanType.getSimpleName());
- }
- this.beanType = beanType;
- this.beanName = beanName;
- }
- int strLen;
- if (str == null || (strLen = str.length()) == 0) {
- return str;
- }
- int i = 0;
- i++;
- }
- if (i == 0) {
- return str;
- } else {
- if (i > 1) i--;
- return new StringBuilder(strLen)
- .append(str.substring(0, i).toLowerCase())
- .append(str.substring(i))
- .toString();
- }
- }
- Collector collector = evaluate();
- return toUris(collector);
- }
- for (int i = 0; i < collector.calls.size(); i++) {
- uris[i] = toUri(collector, i);
- }
- return uris;
- }
- Collector collector = evaluate();
- if (collector.calls.size() != 1) {
- }
- return toUri(collector, 0);
- }
- Collector collector = evaluate();
- if (collector.calls.size() != 1) {
- }
- return collector.calls.get(0);
- }
- Collector collector = evaluate();
- }
- private Collector evaluate() {
- Collector collector = new Collector();
- //noinspection unchecked
- new Class[]{beanType},
- collector);
- try {
- call();
- }
- bean = null;
- return collector;
- }
- return beanName;
- }
- return "bean:" + getBeanName() + "?method=" + collector.calls.get(i);
- }
- calls.add(method.getName());
- return null;
- }
- }
- }