Как вы публикуете тему JMS с Spring JMS? - PullRequest
19 голосов
/ 19 августа 2010

У меня есть компонент, который отправляет сообщения в очередь для обработки другой системой. Следует также периодически публиковать тему о статусе работы. Могу ли я просто использовать тот же 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);

Ответы [ 3 ]

35 голосов
/ 19 августа 2010

Это может показаться немного странным, вам нужно сообщить JmsTemplate, что это тема, а не очередь, установив для свойства pubSubDomain значение true.

Это означает, что вам понадобятся два компонента 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>
5 голосов
/ 20 августа 2010

Если вы создадите назначение в виде пружинного компонента, а не используете имя назначения в своем коде, 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, так как она более стандартна.

2 голосов
/ 07 октября 2015

Если вы можете использовать соглашение об именах для очереди / тем, тогда вы можете реализовать пользовательский 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

...