单个Camel上下文中的单独路由实例

时间:2014-06-17 14:05:50

标签: java spring apache-camel activemq spring-dsl

我使用在ActiveMQ服务中部署的Apache Camel模块。

鉴于我使用Spring DSL并且我在routeContext文件中已经有了路由定义(实现为FilteringRouteContext.xml)(简化):

<routeContext id="filteringRouteContext" xmlns="http://camel.apache.org/schema/spring">
    <route id="myFilteringRoute">
        <from uri="direct:filteringRoute"/>
        <idempotentConsumer messageIdRepositoryRef="idempotentRepository" skipDuplicate="false">
            <simple>${header.JMSType}</simple>
            <filter>
                <property>CamelDuplicateMessage</property>
                <stop/>
            </filter>
        </idempotentConsumer>
    </route>
</routeContext>

接下来,我在其他XML文件中配置了Camel Context(简化):

<import resource="classpath:FilteringRouteContext.xml"/>

    <camelContext xmlns="http://camel.apache.org/schema/spring">

        <routeContextRef ref="filteringRouteContext"/>

        <route id="myRoute1">
            <from uri="activemq:topic:source1" />
            <to uri="direct:filteringRoute" />
            <to uri="activemq:topic:target1" />
        </route>

        <route id="myRoute2">
            <from uri="activemq:topic:source2" />
            <to uri="direct:filteringRoute" />
            <to uri="activemq:topic:target2" />
        </route>

        <route id="myRoute3">
            <from uri="activemq:topic:source3" />
            <to uri="direct:filteringRoute" />
            <to uri="activemq:topic:target3" />
        </route>

    </camelContext>

    <bean id="idempotentRepository"
          class="org.apache.camel.processor.idempotent.MemoryIdempotentRepository">
        <property name="cacheSize" value="10"/>
    </bean>

我希望从myFilteringRoute声明为共享路由(id = filteringRouteContext),使用IoC术语,每个依赖项实例,因此来自单个Camel的每个路由上下文(ID = myRoute1myRoute2myRoute3)应该使用它自己的共享路由实例(id = myFilteringRoute),内部单独state,bean实例等

换句话说,来自Camel Context的每条路线(ID = myRoute1myRoute2myRoute3不应使用相同的共享路线实例 (id = myFilteringRoute),但其拥有完全独立的实例(具有完全独立的内部状态和bean实例)

请考虑我的共享路线(ID为myFilteringRoute)可能会使用更多的bean,这些bean可能有各种范围(singletonprototyperequest等。)

我的问题是:我可以使用单个Camel上下文实现此目标,还是需要将我的路由(id = myRoute1myRoute2myRoute3)放在单独的Camel中上下文?什么是我的问题的最佳解决方案?

是否有重要的性能影响如果我使用多个Camel上下文,并且每个上下文使用bean与ActiveMQ(org.apache.activemq.camel.component.ActiveMQComponent)或其他消耗内部或系统资源的bean进行通信?

或者通过使用Java DSL而不是Spring DSL解决我的问题可能更好?

谢谢。

2 个答案:

答案 0 :(得分:1)

当前的Camel Spring DSL定义是由JAXB在解组xml时创建的。这个定义帮助camel运行时构建处理器并组装它们以路由消息。这样,routeContextRef与你提到的范围没有任何关系。

但是对于你使用bean创建的bean bean,你可以根据需要定义范围,如果Camel Spring DSL中有bean引用,那么camel就可以从Spring Application Context中获取它。

为了回答你的问题,routeContextRef只是提供了一种在camel上下文中共享路由定义实例的方法,如果你不想共享他们的实例,你需要在不同的spring应用程序上下文中创建camel上下文routeContext的不同实例。

答案 1 :(得分:1)

答案是Camel并没有提供自动机制来完成你想做的事情。示例中的所有路由都将共享同一个idempotentRepository实例。唯一的解决方案是提供一个间接级别。

例如,扩展AbstractJdbcMessageIdRepository以提供您自己的实现。然后,可以在查找中包含routeid,以确定是否已经处理了消息。

或者您可以拥有一组存储库,并根据路由ID在主要的idempotentRepository中查找要使用的存储库。

无论你做什么,你都需要使用最外层路由的路由ID来编写代码来区分消息。