簡體   English   中英

如何使用Spring JMS發布JMS主題?

[英]How do you publish a JMS topic with 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);

這可能看起來有點奇怪,您需要通過將其pubSubDomain屬性設置為true來告訴JmsTemplate它是一個主題而不是隊列。

這意味着你將需要兩個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>

如果將目標創建為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技術,因為它更標准。

如果您可以對隊列/主題使用命名約定,那么您可以實現自定義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引用它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM