Подтвердить что ты не робот

Как вы публикуете тему 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);
4b9b3361

Ответ 1

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

Это означает, что вам понадобятся два JmsTemplate beans, один для очереди и один для темы:

<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

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

Ответ 3

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