Dziś pokażę jak w springu można skonfigurować JMS korzystając z ActiveMQ.
Teorii JMS-a nie będę omawiał, odsyłam do dokumentacji.
Spring udostępnia template (podobnie jak do jdbc) pod interfejsem JmsOperations.
Zerknijmy na konfigurację:
Widzimy konfigurację fabryki, template oraz testową kolejkę. Parametry konfiguracji fabryki opisane są w dokumentacji ActiveMQ i są dla tej biblioteki specyficzne.
JmsTemplate część przetwarzania deleguje do :
Przykład:
Stwórzmy beana, który będzie nam wysyłał wiadomości:
Jak odebrać wiadomość? - Potrzeba nam listenera:
I jeszcze klasa:
Czyli teraz spring wie gdzie chcemy wysyłać (<property name="defaultDestination" ref="testQueue"/> w jmsTemplate), wie kto chce odebrać wiadomość. Czas sprawdzić czy śmiga. W tym celu postanowiłem napisać prościutką aplikacyjkę webową (w kolejnym poście opiszę jak w mvc postawić aplikację). Pokażę tylko stronę jsp:
git://github.com/slturo/spring-jms.git
Zerknijmy na konfigurację:
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="vm://embedded?broker.persistent=false"></property> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory"></property> <property name="defaultDestination" ref="testQueue"></property> </bean> <bean id="testQueue" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg value="pl.turo.spring.jms"></constructor-arg> </bean>
Widzimy konfigurację fabryki, template oraz testową kolejkę. Parametry konfiguracji fabryki opisane są w dokumentacji ActiveMQ i są dla tej biblioteki specyficzne.
JmsTemplate część przetwarzania deleguje do :
- MessageConverter - odpowiada za konwersję pomiędzy obiektem przekazanym do wysłania z wiadomością (javax.jms.Message). Domyślny SimpleMessageConverter potrafi konvertować typy:
- String - TextMessage
- Serializable - ObjectMessage
- Map - MapMessage
- byte[] - BytesMessage
- DestinationResolver - odpowiada za to gdzie wysłać wiadomość (jeśli korzystamy z metod niepodających explicite gdzie wysyłamy). Domyślny to DynamicDestinationResolver.
Przykład:
Stwórzmy beana, który będzie nam wysyłał wiadomości:
public class JmsBatchProcessorImpl implements JmsBatchProcessor { private JmsOperations jmsOperations; public JmsBatchProcessorImpl(JmsOperations jmsOperations) { this.jmsOperations = jmsOperations; } @Override public void sentMessage(String message) { jmsOperations.convertAndSend(message); } }Dorzućmy do konfigu springa:
<bean id="jmsBatchProcessor" class="pl.turo.spring.jms.producer.JmsBatchProcessorImpl"> <constructor-arg ref="jmsTemplate"/> </bean>
Jak odebrać wiadomość? - Potrzeba nam listenera:
<jms:listener-container> <jms:listener ref="messageListener" method="consumeMessage" destination="pl.turo.spring.jms"/> </jms:listener-container> <bean id="messageListener" class="pl.turo.spring.jms.consumer.MessageListenerImpl" />
I jeszcze klasa:
public class MessageListenerImpl implements MessageListener { private List<String> messages = new ArrayList<String>(); @Override public void consumeMessage(String message) { messages.add(message); } public List<String> getMessages() { return messages; } }MessageListener to mój własny interfejs. Listener nie musi implementować żadnego specjalnego interfejsu, nie ma żadnej adnotacji. Wystarczy konfig w xml-u przedstawiony wyżej. Widać że mój listener trzyma w sobie listę odebranych wiadomości - tak, wiem że to singleton, ale dla przejrzystości przykładu pozwalam sobie na to.
Czyli teraz spring wie gdzie chcemy wysyłać (<property name="defaultDestination" ref="testQueue"/> w jmsTemplate), wie kto chce odebrać wiadomość. Czas sprawdzić czy śmiga. W tym celu postanowiłem napisać prościutką aplikacyjkę webową (w kolejnym poście opiszę jak w mvc postawić aplikację). Pokażę tylko stronę jsp:
<P>Dodaj wiadomość do kolejki: </P> <form action="sent" name="form" method="post"> <input type="text" name="value"/> </form> <P>Przetworzone wiadomości:<br/> ${messages} </P>Sewer odbiera z formularza wiadomość i wysyła do kolejki, potrafi też zwrócić odebrane wiadomości:
@Controller public class HomeController { @Autowired private JmsBatchProcessor jmsBatchProcessor; @Autowired private MessageListener messageListener; @RequestMapping(value = "/", method = RequestMethod.GET) public String home(Locale locale, Model model) { model.addAttribute("messages", messageListener.getMessages()); return "home"; } @RequestMapping(value = "/sent", method = RequestMethod.POST) public String sentMessage(@RequestParam("value") String message) { jmsBatchProcessor.sentMessage(message); return "redirect:/"; } }Jeśli coś w kontrolerze jest niejasne - spokojnie, czytajcie kolejne posty i się rozjaśni. Musicie mi uwierzyć na słowo, że działa, bądź pobierzcie sobie projekt i sami sprawdźcie :-). Postanowiłem projekty udostępniać na githubie:
git://github.com/slturo/spring-jms.git
Brak komentarzy:
Prześlij komentarz