Advanced configuration of CamelContext using Spring has been edited by Claus Ibsen (Jun 12, 2009).

(View changes)

Content:

Advanced configuration of CamelContext using Spring

When using Spring the CamelContext can be pre configured based on defined beans in spring XML and/or system properties.
This wiki page documentes these features.

What can be configured

The following functions can be configured:

Camel will configure these functions by doing a lookup in the Spring bean registry to find beans of the given type
When Camel finds and uses any of these it logs at INFO level.

The following list all requires at most 1 beans defined. If there are more than 1 bean of this type, then Camel will not use it.

Type Number of beans Description
PackageScanClassResolver 0..1 To use a 3rd party package scan resolver. More details at Pluggable Class Resolver.
ClassResolver 0..1 To use a 3rd party class resolver. More details at Pluggable Class Resolvers.
FactoryFinderResolver 0..1 To use a 3rd party factory finder.
LifecycleStrategy 0..1 To use a 3rd party lifecycle strategy. By default Camel uses a JMX aware that does JMX instrumentation.
Registry 0..1 To use a 3rd party bean registry. By default Camel will use Spring ApplicationContext as registry.
Debugger 0..1 To use a Debugger usually for tooling.
Tracer 0..1 To use a 3rd party Tracer.
TraceFormatter 0..1 To use a bean that has the tracing options configured.
HandleFault 0..1 To use a 3rd part fault handler to handle FAULT messages.
Delayer 0..1 To use a 3rd part Delayer.

And the following options have support for any number of beans defined.

Type Number of beans Description
InterceptStrategy 0..n To use your own Intercept that intercepts every processing steps in all routes in the CamelContext. For instance you can use this to do an AOP like performance timer interceptor.

Using container wide interceptors

Imagine that you have multiple CamelContext and you want to configure that they all use the same container wide interceptor. How do we do that? Well we can leverage the fact that Camel can auto detect and use custom interceptors. So what we simply do is to define our interceptor in the spring xml file. The sample below does this and also define 2 camel contexts. The sample is based on unit test.

<!-- here we define a spring bean that is our container wide interceptor
     its important to notice that the class ContainerWideInterceptor implements
     org.apache.camel.spi.InterceptStrategy that allows us to plugin our interceptors
     Camel will at startup automatic look for any beans in spring registry that is an
     instance of org.apache.camel.spi.InterceptStrategy and add it as interceptor
     to all its routes. Using this we are capable of defining container wide interceptors
     that gets used in all camel contests we define with spring -->
<bean id="myInterceptor" class="org.apache.camel.spring.interceptor.ContainerWideInterceptor"/>

<!-- here we have the 1st CamelContext -->
<camelContext id="camel1" xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="direct:one"/>
        <to uri="mock:result"/>
    </route>
</camelContext>

<!-- and there we have the 2nd CamelContext -->
<camelContext id="camel2" xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="direct:two"/>
        <to uri="log:two"/>
        <to uri="mock:result"/>
    </route>
</camelContext>

Okay lets build our interceptor to simply count the number of interceptions. This is quite easy as we can just implement this logic in our implementation directly as the code below illustrates:

public class ContainerWideInterceptor implements InterceptStrategy {

    private static final transient Log LOG = LogFactory.getLog(ContainerWideInterceptor.class);
    private static int count;

    public Processor wrapProcessorInInterceptors(final ProcessorDefinition processorDefinition,
                                                 final Processor target, final Processor nextTarget) throws Exception {

        // as this is based on an unit test we are a bit lazy and just create an inlined processor
        // where we implement our interception logic.
        return new Processor() {
            public void process(Exchange exchange) throws Exception {
                // we just count number of interceptions
                count++;
                LOG.info("I am the container wide interceptor. Intercepted total count: " + count);
                // its important that we delegate to the real target so we let target process the exchange
                target.process(exchange);
            }

            @Override
            public String toString() {
                return "ContainerWideInterceptor[" + target + "]";
            }
        };
    }

    public int getCount() {
        return count;
    }
}

When Camel boots up it logs at INFO level the container wide interceptors it have found:

INFO  CamelContextFactoryBean        - Using custom intercept strategy with id: myInterceptor and implementation:org.apache.camel.spring.interceptor.containerwideintercep...@b84c44

Notice: If we have more than 1 container wide interceptor, we can just define them as spring bean. Camel will find and use them.

See Also

Reply via email to