Как опубликовать тему JMS с помощью Spring JMS?

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

person wsb3383    schedule 19.08.2010    source источник


Ответы (3)


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

Это означает, что вам понадобятся два 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>
person skaffman    schedule 19.08.2010

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

person Eran Harel    schedule 20.08.2010

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

person Gian Marco    schedule 07.10.2015
comment
У меня отлично сработало. Если вы добавите @Component в DestinationResolver, вам даже не нужно устанавливать его в JmsTemplate - person danielnovy; 13.01.2018
comment
@danielnovy, если вы нашли ответ полезным, мы будем благодарны за голосование :) - person Gian Marco; 14.01.2018