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