Статьи

Не используйте JmsTemplate весной!

JmsTemplate легко для простой отправки сообщений. Что если мы хотим добавить заголовки, перехватить или преобразовать сообщение? Тогда мы должны написать больше кода. Итак, как мы можем решить эту общую задачу с большей настраиваемостью вместо большего количества кода? Сначала рассмотрим JMS весной.

Опции Spring JMS

  1. JmsTemplate — отправлять и получать сообщения встроенными

    1. Используйте методы send () / convertAndSend () для отправки сообщений
    2. Используйте методы receive () / receiveAndConvert () для получения сообщений. ВНИМАНИЕ: это методы блокировки! Если в пункте назначения нет сообщений, он будет ждать, пока сообщение не будет получено или не истечет время ожидания.
  2. MessageListenerContainer — асинхронный прием сообщений JMS путем опроса адресатов JMS и направления сообщений в методы обслуживания или MDB

И JmsTemplate, и MessageListenerContainer были успешно реализованы в приложениях Spring. Если нам нужно сделать что-то немного другое, мы вводим новый код. Что возможно могло пойти не так?

Расширяемость в будущем?

Во многих проектах возникают новые варианты использования, такие как:

  • Направлять сообщения в разные пункты назначения, основываясь на значениях заголовка или содержимом?
  • Записать содержимое сообщения?
  • Добавить значения заголовка?
  • Буферизировать сообщения?
  • Улучшенный ответ и обработка ошибок?
  • Внести изменения в конфигурацию без перекомпиляции ?
  • и больше…

Теперь нам нужно провести рефакторинг кода и ввести новый код и тестовые случаи, запустить его через QA и т. Д. И т. Д.


Более настраиваемое решение!

Настало время закончить Spring JmsTemplate и поиграть с большими детьми. Мы можем легко сделать это с потоком Spring Integration.

Как это делается с помощью Spring Integration

Здесь у нас есть диаграмма, иллюстрирующая 3 простых компонента Spring Integration, заменяющих отправку JmsTemplate.

  1. Создайте интерфейс шлюза — интерфейс, определяющий методы, которые принимают тип данных, которые вы хотите отправить, и любые необязательные значения заголовка.
  2. Определить канал — канал, соединяющий наши конечные точки
  3. Определить исходящий адаптер JMS — отправляет сообщение вашему поставщику JMS (ActiveMQ, RabbitMQ и т. Д.)

Просто внедрите это в наши классы обслуживания и вызовите методы.

Немедленные выгоды

  • Добавить заголовок и значения заголовка с помощью методов, определенных в интерфейсе
  • Простой вызов методов Gateway из наших классов обслуживания
  • Методы с несколькими шлюзами
  • Настройте места назначения уровня уровня или класса

Будущие выгоды

  • Измените адаптер JMS (односторонний) на шлюз JMS (двусторонний) для обработки ответов от JMS
  • Мы можем изменить канал в очередь (буферизованный) канал
  • Мы можем подключить трансформатор для преобразования сообщений
  • Мы можем подключить дополнительные пункты назначения, подключить маршрутизатор «заголовок (ключ), значение заголовка или содержимое» и добавить еще один адаптер
  • Мы можем подключить другие входящие адаптеры, получающие данные из другого источника, например SMTP, FTP, File и т. Д.
  • Прослушайте канал, чтобы отправить копию сообщения в другое место.
  • Измените канал на канал адаптера регистрации, который предоставил бы нам регистрацию сообщений, проходящих через
  • Добавьте опцию « message-history » в нашу конфигурацию SI, чтобы отслеживать сообщение по его маршруту
  • и больше…

Оптимальное решение для отправки JMS

Интерфейс Spring Integration Gateway

Шлюз обеспечивает одно или двухстороннее взаимодействие с Spring Integration. Если метод возвращает void, он по своей сути односторонний.

Интерфейс MyJmsGateway, имеет один метод Gateway, объявленный sendMyMessage (). Когда этот метод вызывается вашим классом обслуживания, первый аргумент войдет в поле заголовка сообщения с именем «myHeaderKey», второй аргумент переходит в полезную нагрузку.

package com.gordondickens.sijms; import org.springframework.integration.annotation.Gateway;import org.springframework.integration.annotation.Header; public interface MyJmsGateway {    @Gateway    public void sendMyMessage(@Header("myHeaderKey") String s, Object o);}

Конфигурация Spring Integration

Поскольку интерфейс проксируется во время выполнения, нам необходимо настроить шлюз через XML.

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xmlns:jms="http://www.springframework.org/schema/integration/jms"        xmlns:si="http://www.springframework.org/schema/integration"        xsi:schemaLocation="http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.0.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd http://www.springframework.org/schema/beans           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">     <import resource="classpath:META-INF/spring/amq-context.xml"/>     <!-- Pickup the @Gateway annotation -->    <si:annotation-config/>     <si:poller default="true">      <si:interval-trigger interval="500"/>    </si:poller>     <!-- Define the channel (pipe) connecting the endpoints -->    <si:channel id="myRequestChannel"/>     <!-- Configure the Gateway to Send on the channel -->    <si:gateway id="myJmsGateway"        service-interface="com.gordondickens.sijms.MyJmsGateway"        default-request-channel="myRequestChannel"/>     <!-- Send message to JMS -->    <jms:outbound-channel-adapter channel="myRequestChannel"        connection-factory="connectionFactory"        destination="my.inbound.queue"/></beans>

Отправка сообщения

package com.gordondickens.sijms; import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @ContextConfiguration("classpath:/com/gordondickens/sijms/JmsSenderTests-context.xml")@RunWith(SpringJUnit4ClassRunner.class)public class JmsSenderTests {     @Autowired    MyJmsGateway myJmsGateway;     @Test    public void testJmsSend() {        myJmsGateway.sendMyMessage("myHeaderValue", "MY PayLoad");    }}

Резюме

  • Простая реализация
  • Вызовите метод для отправки сообщения в JMS — Very SOA, а?
  • Гибкая конфигурация
  • Переконфигурируйте и перезапустите БЕЗ перекомпиляции — СЛАДКИЙ!