Jak opublikować temat JMS za pomocą Spring JMS?
Mam komponent, który wysyła wiadomości do kolejki do obsługi przez inny system. Powinien także raz na jakiś czas publikować temat o statusach zadań. Czy mogę użyć tego samego JmsTemplate używanego do wysyłania do kolejki i publikowania do tematu?
Utworzyłem nowy temat w ActiveMQ, z tym wyjątkiem, że gdy wysyłam z JmsTemplate wiadomość, powstaje nowa kolejka z nazwą tematu z wysłaną wiadomością( zamiast wysyłania danych do rzeczywistego tematu), co robię źle tutaj?
Oto mój config:
<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 jest klasą, której używam do wysyłania wiadomości kolejki (i działa), Czy Mogę też użyć jej do opublikowania tematu?
Czy mogę użyć tego do wysyłania kolejek i publikowania tematów?:
jmsTemplate.convertAndSend("TOPIC_NAME" /* or queue name */, message);
3 answers
Może to wydawać się trochę dziwne, musisz powiedzieć JmsTemplate, że jest to temat, a nie Kolejka, ustawiając jego właściwość pubSubDomain
na true
.
Oznacza to, że będziesz potrzebował dwóch JmsTemplate
fasolek, jednej do kolejki i jednej do tematu:
<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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-19 07:40:05
Jeśli utworzysz cel jako fasolkę wiosenną zamiast używać nazwy celu w kodzie, Spring nie będzie musiał wiedzieć, czy jest to temat, czy kolejka. W przeciwnym razie rozwiązanie zaproponowane powyżej powinno również działać.
Miejsca docelowe AMQ JMS mogą być tworzone przez bezpośrednie utworzenie ich instancji:
<bean id="destination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="TOPIC_NAME" />
</bean>
Lub pobieranie z JNDI:
<bean id="topic" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="TOPIC_NAME"/>
<property name="jndiTemplate" ref="jmsJndiTemplate"/>
</bean>
Wolę technikę JNDI, ponieważ jest bardziej standardowa.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-20 12:53:27
Jeśli nie masz nic przeciwko używaniu konwencji nazewnictwa dla queue/topics, możesz zaimplementować własne 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);
}
}
I odwołaj się do niego za pomocą JmsTemplate.setDestinationResolver
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-07 16:32:00