如何使用Spring JMS发布JMS主题?

2022-09-01 15:11:30

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

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

这是我的配置:

<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <constructor-arg ref="amqConnectionFactory" />
    <property name="exceptionListener" ref="jmsExceptionListener" />
    <property name="sessionCacheSize" value="100" />
</bean>

<!--  JmsTemplate Definition -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <constructor-arg ref="connectionFactory" />
</bean>


<bean id="messageFacade" class="org.foo.MessageFacadeJms">
    <property name="jmsTemplate" ref="jmsTemplate" />
</bean>

MessageFacadeJms是我用来发送队列消息的类(它有效),我也可以用它来发布主题吗?

我可以用它来同时执行队列发送和主题发布吗?

jmsTemplate.convertAndSend("TOPIC_NAME" /* or queue name */, message);

答案 1

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

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

<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>

答案 2

如果可以对队列/主题使用命名约定,则可以实现自定义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


推荐