Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用SpringJMS发布JMS主题?_Java_Spring_Jms_Activemq - Fatal编程技术网

Java 如何使用SpringJMS发布JMS主题?

Java 如何使用SpringJMS发布JMS主题?,java,spring,jms,activemq,Java,Spring,Jms,Activemq,我有一个组件,它将消息发送到另一个系统处理的队列。它还应该每隔一段时间发布一个关于工作状态的主题。我可以使用与发送到队列和发布到主题相同的JmsTemplate吗 我在ActiveMQ中创建了一个新的主题,除了当我从JmsTemplate发送一条消息时,一个主题名为的新队列将与发送的消息一起创建(而不是将数据发送到实际的主题),我在这里做错了什么 这是我的配置: 这可能有点奇怪,您需要通过将其pubSubDomain属性设置为true来告诉JmsTemplate它是一个主题而不是一个队列 这

我有一个组件,它将消息发送到另一个系统处理的队列。它还应该每隔一段时间发布一个关于工作状态的主题。我可以使用与发送到队列和发布到主题相同的JmsTemplate吗

我在ActiveMQ中创建了一个新的主题,除了当我从JmsTemplate发送一条消息时,一个主题名为的新队列将与发送的消息一起创建(而不是将数据发送到实际的主题),我在这里做错了什么

这是我的配置:


这可能有点奇怪,您需要通过将其
pubSubDomain
属性设置为
true
来告诉JmsTemplate它是一个主题而不是一个队列

这意味着您需要两个
JmsTemplate
bean,一个用于队列,一个用于主题:

<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
   <constructor-arg ref="connectionFactory" />
   <property name="pubSubDomain" value="false"/>
</bean>

<bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
   <constructor-arg ref="connectionFactory" />
   <property name="pubSubDomain" value="true"/>
</bean>

如果将目的地创建为Springbean,而不是在代码中使用目的地名称,spring将不需要知道它是主题还是队列。否则,上述建议的解决方案也会起作用

AMQ JMS目的地可以通过直接实例化来创建:

  <bean id="destination" class="org.apache.activemq.command.ActiveMQTopic">
    <constructor-arg value="TOPIC_NAME" />
  </bean>

或从JNDI获取:

<bean id="topic" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="TOPIC_NAME"/>
        <property name="jndiTemplate" ref="jmsJndiTemplate"/> 
</bean>


我更喜欢JNDI技术,因为它更标准。

如果您可以为队列/主题使用命名约定,那么您可以实现自定义的
org.springframework.jms.support.destination.DestinationResolver

public class NamingDestinationResolver implements DestinationResolver {
   public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain) throws JMSException {
      if (destinationName.endsWith("Queue")) {
         return session.createQueue(destinationName);
      } else if (destinationName.endsWith("Topic")) {
         return session.createTopic(destinationName);
      }
      throw new RuntimeException("Naming convention not respected for destination " + destinationName);
   }
}

并使用
JmsTemplate引用它。setDestinationResolver

非常适合我。如果将@Component添加到DestinationResolver,甚至不需要将其设置为打开JmsTemplate@danielnovy如果您觉得答案有用,请投赞成票:)
public class NamingDestinationResolver implements DestinationResolver {
   public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain) throws JMSException {
      if (destinationName.endsWith("Queue")) {
         return session.createQueue(destinationName);
      } else if (destinationName.endsWith("Topic")) {
         return session.createTopic(destinationName);
      }
      throw new RuntimeException("Naming convention not respected for destination " + destinationName);
   }
}
public class NamingDestinationResolver implements DestinationResolver {
   public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain) throws JMSException {
      if (destinationName.endsWith("Queue")) {
         return session.createQueue(destinationName);
      } else if (destinationName.endsWith("Topic")) {
         return session.createTopic(destinationName);
      }
      throw new RuntimeException("Naming convention not respected for destination " + destinationName);
   }
}