我使用在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 = myRoute1
,myRoute2
,myRoute3
)应该使用它自己的共享路由实例(id = myFilteringRoute
),内部单独state,bean实例等
换句话说,来自Camel Context的每条路线(ID = myRoute1
,myRoute2
,myRoute3
)不应使用相同的共享路线实例 (id = myFilteringRoute
),但其拥有完全独立的实例(具有完全独立的内部状态和bean实例)
请考虑我的共享路线(ID为myFilteringRoute
)可能会使用更多的bean,这些bean可能有各种范围(singleton
,prototype
,request
等。)
我的问题是:我可以使用单个Camel上下文实现此目标,还是需要将我的路由(id = myRoute1
,myRoute2
,myRoute3
)放在单独的Camel中上下文?什么是我的问题的最佳解决方案?
是否有重要的性能影响如果我使用多个Camel上下文,并且每个上下文使用bean与ActiveMQ(org.apache.activemq.camel.component.ActiveMQComponent
)或其他消耗内部或系统资源的bean进行通信?
或者通过使用Java DSL而不是Spring DSL解决我的问题可能更好?
谢谢。
答案 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来编写代码来区分消息。