Първи стъпки с Spring JMS

1. Общ преглед

Spring предоставя рамка за интеграция на JMS, която опростява използването на JMS API. Тази статия представя основните понятия за такава интеграция.

2. Зависимост на Maven

За да използваме Spring JMS в нашето приложение, трябва да добавим необходимите артефакти в pom.xml :

 org.springframework spring-jms 4.3.3.RELEASE  

Най-новата версия на артефакта можете да намерите тук.

3. JmsTemplate

Класът JmsTemplate обработва създаването и освобождаването на ресурси при изпращане или синхронно получаване на съобщения.

Следователно класът, който използва този JmsTemplate, трябва само да реализира интерфейси за обратно извикване, както е посочено в дефиницията на метода.

Започвайки с пролет 4.1, JmsMessagingTemplate е изграден върху JmsTemplate, който осигурява интеграция с абстракцията за съобщения, т.е. org.springframework.messaging.Message. Това от своя страна ни позволява да създадем съобщение, което да изпратим по общ начин.

4. Управление на връзката

За да се свържем и да можем да изпращаме / получаваме съобщения, трябва да конфигурираме ConnectionFactory .

А ConnectionFactory е един от JMS прилагат обекти, които са конфигурирани предварително от администратор . Клиент с помощта на конфигурацията ще осъществи връзката с JMS доставчик.

Spring осигурява 2 вида ConnectionFactory :

  • SingleConnectionFactory - е реализация наинтерфейса ConnectionFactory , който ще върне една и съща връзка при всичкиповиквания createConnection () и ще игнорира повикванията за затваряне ()
  • CachingConnectionFactory - разширява функционалността на SingleConnectionFactory и добавя я подобрява с кеширане на Sessions , MessageProducers и MessageConsumers

5. Управление на дестинацията

Както беше обсъдено по-горе, заедно с ConnectionFactory , дестинациите също са обекти, управлявани от JMS и могат да се съхраняват и извличат от JNDI.

Spring предоставя общи преобразуватели като DynamicDestinationResolver и специфични резолвери като JndiDestinationResolver .

В JmsTemplate ще делегира решението на името на дестинация за един от внедряванията Базирайки се на нашата селекция.

Той също така ще предостави свойство, наречено defaultDestination - което ще се използва с операции за изпращане и получаване , които не се отнасят до конкретна дестинация.

6. Преобразуване на съобщения

Spring JMS би бил непълен без подкрепата на Message Converters.

Стратегията за преобразуване по подразбиране, използвана от JmsTemplate както за операции ConvertAndSend (), така и за ReceiveAndConvert () , е класът SimpleMessageConverter .

SimpleMessageConverter е в състояние да обработва TextMessages , BytesMessages , MapMessages и ObjectMessages . Този клас реализира интерфейса MessageConverter .

Освен SimpleMessageConverter , Spring JMS предоставя някои други класове MessageConverter , като MappingJackson2MessageConverter , MarshallingMessageConverter , MessagingMessageConverter .

Освен това можем да създадем персонализирана функционалност за преобразуване на съобщения, просто чрез внедряване на методите toMessage () и FromMessage () на интерфейса MessageConverter .

Нека видим примерен кодов фрагмент за внедряване на персонализиран MessageConverter ,

public class SampleMessageConverter implements MessageConverter { public Object fromMessage(Message message) throws JMSException, MessageConversionException { //... } public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException { //... } }

7. Примерен пролетен JMS

В този раздел ще видим как да използваме JmsTemplate за изпращане и получаване на съобщения.

Методът по подразбиране за изпращане на съобщението е JmsTemplate.send () . Той има два ключови параметъра, от които първият параметър е дестинацията на JMS, а вторият параметър е реализация на MessageCreator. JmsTemplate използва метода за обратно извикване на MessageCreator createMessage () за изграждане на съобщението.

JmsTemplate.send () е добър за изпращане на обикновени текстови съобщения, но за да изпраща потребителски съобщения, JmsTemplate има друг метод, наречен c onvertAndSend () .

По-долу можем да видим изпълнението на тези методи:

public class SampleJmsMessageSender { private JmsTemplate jmsTemplate; private Queue queue; // setters for jmsTemplate & queue public void simpleSend() { jmsTemplate.send(queue, s -> s.createTextMessage("hello queue world")); }
 public void sendMessage(Employee employee) { System.out.println("Jms Message Sender : " + employee); Map map = new HashMap(); map.put("name", employee.getName()); map.put("age", employee.getAge()); jmsTemplate.convertAndSend(map); } }

По-долу е класът на получателя на съобщения, наричаме го като управляван от съобщения POJO (MDP). Можем да видим, че класът SampleListener изпълнява интерфейса MessageListener и предоставя специфичната за текста реализация за метода на интерфейса onMessage ().

Освен метода onMessage () , нашият клас SampleListener нарича и метод receiveAndConvert () за получаване на персонализирани съобщения:

public class SampleListener implements MessageListener { public JmsTemplate getJmsTemplate() { return getJmsTemplate(); } public void onMessage(Message message) { if (message instanceof TextMessage) { try { String msg = ((TextMessage) message).getText(); System.out.println("Message has been consumed : " + msg); } catch (JMSException ex) { throw new RuntimeException(ex); } } else { throw new IllegalArgumentException("Message Error"); } } public Employee receiveMessage() throws JMSException { Map map = (Map) getJmsTemplate().receiveAndConvert(); return new Employee((String) map.get("name"), (Integer) map.get("age")); } }

Видяхме как да приложим MessageListener и по-долу виждаме конфигурацията в контекста на пролетното приложение:

DefaultMessageListenerContainer е контейнерът за слушане на съобщения по подразбиране, който Spring предоставя заедно с много други специализирани контейнери.

8. Basic Configuration With Java Annotations

The @JmsListener is the only annotation required to convert a method of a normal bean into a JMS listener endpoint. Spring JMS provides many more annotations to ease the JMS implementation.

We can see some of the sample classes annotated below:

@JmsListener(destination = "myDestination") public void SampleJmsListenerMethod(Message order) { ... }

In order to add multiple listeners to a single method we just need to add multiple @JmsListener annotations.

We need to add the @EnableJms annotation to one of our configuration classes to support the @JmsListener annotated methods:

@Configuration @EnableJms public class AppConfig { @Bean public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory()); return factory; } }

9. Error Handler

We can also configure a custom error handler for our message listener container.

Let's first implement the org.springframework.util.ErrorHandler interface:

@Service public class SampleJmsErrorHandler implements ErrorHandler { // ... logger @Override public void handleError(Throwable t) { LOG.warn("In default jms error handler..."); LOG.error("Error Message : {}", t.getMessage()); } }

Note that we have overridden the handleError() method, which simply logs the error message.

And then, we need to reference our error handler service in the DefaultJmsListenerConnectionFactory using the setErrorHandler() method:

@Bean public DefaultJmsListenerContainerFactorybjmsListenerContainerFactory() { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory()); factory.setErrorHandler(sampleJmsErrorHandler); return factory; }

With this, our configured error handler will now catch any unhandled exceptions and log the message.

Optionally, we can also configure the error handler using the plain-old XML configurations by updating our appContext.xml:

10. Conclusion

In this tutorial, we discussed the configuration and basic concepts of Spring JMS. We also had a brief look at the Spring-specific JmsTemplate classes which are used for sending and receiving messages.

Можете да намерите внедряването на кода в проекта GitHub.