我应该如何在其他节点的动态列表上生成JMS端点?

时间:2013-06-24 15:57:07

标签: jms activemq apache-camel

从我的集线器系统,我希望能够与其他节点的动态列表进行通信。我将在每个系统上有一个代理和一个静态队列名称。因此,我可以通过定位其经纪人来解决每个节点。我有一些工作,每个目的地使用一个端点,但Camel JMS doc暗示这不是一个好主意。我可能只有不到100个端点,但我很想知道是否有更好的方法。

如果我可以将代理URI指定为端点URI的一部分,那么动态收件人列表将是完美的,但我看不出如何做到这一点。

使用单个中央代理并让其他节点从中获取可能更为明智,但我要求这些节点不需要配置中心位置。因此,必须发送消息,而不是收集消息。

提前致谢。

1 个答案:

答案 0 :(得分:2)

首先,如果在应用程序中插入JNDI注册表,可能会更容易。 Apache ActiveMQ已经附带了一个集成的轻量级JNDI提供程序。或者,您可以使用某些应用服务器的JNDI或其他轻量级实现。然后使用代理目标(ConnectionFactory实例)填充此注册表。

在您的上下文中初始化JndiTemplate:

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
    <props>
            <prop key="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</prop>
            <prop key="java.naming.provider.url">tcp://localhost:61616</prop>
    </props>
    </property>
</bean>

之后,您可以使用注册表中的目标在动态路由器的端点上指定сonnectionFactory属性:

public class FooDynamicRouter {

  private AbstractApplicationContext ctx;
  private JndiTemplate jndiTemplate;

  @Consume(uri = "activemq:outgoing")
  @DynamicRouter
  public String route(@XPath("/destination/code") String code, Document body) {
     if (code != null) {
       if (!ctx.containsBean("cf"+code)) {
          ctx.getBeanFactory().registerSingleton("cf"+code, jndiTemplate.lookup("cf"+code));
       }    
       return "jms:queue:foo?connectionFactory=cf"+code;
     } else {
       return null;
     }
  }
}

也许有更简单的方法在运行时将JNDI注册表项与应用程序上下文绑定,但我没有找到它。