2010-08-19 5 views
12

У меня есть компонент, который отправляет сообщения в очередь для обработки другой системой. Он также должен публиковать тему о статусах работы каждый раз в то время. Могу ли я использовать один и тот же JmsTemplate, используемый для отправки в очередь И для публикации в теме?Как вы публикуете тему JMS с помощью Spring JMS?

Я создал новую тему в 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); 

ответ

28

Это может показаться немного странным, вам нужно сказать 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

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

1

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

+0

работал отлично для меня. Если вы добавите @Component в DestinationResolver, вам даже не нужно устанавливать его на JmsTemplate – danielnovy

+0

@ danielnovy, если вы найдете ответ полезным, голос будет оценен по достоинству :) –

Смежные вопросы