1. Введение
В предыдущих статьях мы узнали, как настроить проект с помощью Spring JMS. Если вы ознакомитесь со статьей Введение в обмен сообщениями с Spring JMS , вы заметите, что он настроен с использованием XML. В этой статье будут использованы преимущества, представленные в версии Spring 4.1, и сконфигурирован проект JMS с использованием только конфигурации Java.
В этом примере мы также увидим, как легко можно настроить проект с помощью Spring Boot .
Прежде чем мы начнем, просто отметьте, что, как обычно, вы можете взглянуть на исходный код проекта, используемый в примерах ниже.
Смотрите пример проекта на github .
Разделы:
- Введение.
- Пример приложения.
- Настройка проекта.
- Простой пример со слушателем JMS.
- Отправка ответа в другую очередь с помощью @SendTo.
- Вывод.
2. Пример приложения
Приложение использует клиентскую службу для отправки заказов в очередь JMS, где JMS-слушатель будет зарегистрирован и обработать эти заказы. После получения слушатель сохранит заказ через сервис Store:
Мы будем использовать класс Order для создания заказов:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public class Order implements Serializable { private static final long serialVersionUID = -797586847427389162L; private final String id; public Order(String id) { this .id = id; } public String getId() { return id; } } |
Прежде чем перейти к первому примеру, мы сначала рассмотрим, как строится структура проекта.
3. Настройка проекта
3.1 Настройка pom.xml
Первое, что нужно сделать, это определить артефакт spring-boot-starter-parent как наш родительский pom.
1
2
3
4
5
6
|
< parent > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-parent</ artifactId > < version >1.2.3.RELEASE</ version > < relativePath /> <!-- lookup parent from repository --> </ parent > |
Этот родительский элемент в основном устанавливает несколько значений по умолчанию Maven и обеспечивает управление зависимостями для основных зависимостей, которые мы будем использовать, например версию Spring (которая является 4.1.6).
Важно отметить, что этот родительский pom определяет версию многих библиотек, но он не добавляет никакой зависимости к нашему проекту. Так что не беспокойтесь о получении библиотек, которые вы не будете использовать.
Следующим шагом является установка основных зависимостей для Spring Boot:
1
2
3
4
|
< dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter</ artifactId > </ dependency > |
В дополнение к основным библиотекам Spring, эта зависимость обеспечит автоматическую настройку Spring Boot. Это позволит каркасу попытаться автоматически настроить конфигурацию на основе добавленных вами зависимостей.
Наконец, мы добавим зависимость Spring JMS и брокер сообщений ActiveMQ, оставив весь файл pom.xml следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
< groupId >xpadro.spring</ groupId > < artifactId >jms-boot-javaconfig</ artifactId > < version >0.0.1-SNAPSHOT</ version > < packaging >jar</ packaging > < name >JMS Spring Boot Javaconfig</ name > < parent > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-parent</ artifactId > < version >1.2.3.RELEASE</ version > < relativePath /> <!-- lookup parent from repository --> </ parent > < properties > < project.build.sourceEncoding >UTF-8</ project.build.sourceEncoding > < start-class >xpadro.spring.jms.JmsJavaconfigApplication</ start-class > < java.version >1.8</ java.version > < amq.version >5.4.2</ amq.version > </ properties > < dependencies > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter</ artifactId > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-jms</ artifactId > </ dependency > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-test</ artifactId > < scope >test</ scope > </ dependency > < dependency > < groupId >org.apache.activemq</ groupId > < artifactId >activemq-core</ artifactId > < version >${amq.version}</ version > </ dependency > </ dependencies > < build > < plugins > < plugin > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-maven-plugin</ artifactId > </ plugin > </ plugins > </ build > |
3.2 Настройка Spring с помощью Java Config
Классу конфигурации просто нужно настроить встроенный брокер сообщений. Остальное автоматически настраивается Spring Boot:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@SpringBootApplication public class JmsJavaconfigApplication { private static final String JMS_BROKER_URL = "vm://embedded?broker.persistent=false,useShutdownHook=false" ; @Bean public ConnectionFactory connectionFactory() { return new ActiveMQConnectionFactory(JMS_BROKER_URL); } public static void main(String[] args) { SpringApplication.run(JmsJavaconfigApplication. class , args); } } |
Мы использовали @SpringBootApplication вместо обычной аннотации @Configuration. Эта аннотация Spring Boot также помечена @Configuration. Кроме того, он устанавливает другую конфигурацию, например автоматическую настройку Spring Boot:
1
2
3
4
5
6
7
8
|
@Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME) @Documented @Inherited @Configuration @EnableAutoConfiguration @ComponentScan public @interface SpringBootApplication { |
Теперь все готово. Мы увидим, как настроить JMS-слушатель в примере в следующем разделе, так как он настроен с аннотацией.
4. Простой пример со слушателем JMS
4.1 Отправка заказа в очередь JMS
Класс ClientService отвечает за отправку нового заказа в очередь JMS. Для этого он использует JmsTemplate:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
@Service public class ClientServiceImpl implements ClientService { private static final String SIMPLE_QUEUE = "simple.queue" ; private final JmsTemplate jmsTemplate; @Autowired public ClientServiceImpl(JmsTemplate jmsTemplate) { this .jmsTemplate = jmsTemplate; } @Override public void addOrder(Order order) { jmsTemplate.convertAndSend(SIMPLE_QUEUE, order); } } |
Здесь мы используем JmsTemplate для преобразования нашего экземпляра Order и отправки его в очередь JMS. Если вы предпочитаете отправлять сообщение напрямую через отправленное сообщение, вместо этого вы можете использовать новый JmsMessagingTemplate . Это предпочтительнее, поскольку в нем используется более стандартизированный класс Message .
4.2 Получение заказа, отправленного в очередь JMS
Зарегистрировать JMS-слушатель в контейнере JMS-слушателя так же просто, как добавить аннотацию @JmsListener к методу, который мы хотим использовать. Это создаст контейнер слушателя JMS под крышками, который будет принимать сообщения, отправленные в указанную очередь, и делегировать их нашему классу слушателя:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
@Component public class SimpleListener { private final StoreService storeService; @Autowired public SimpleListener(StoreService storeService) { this .storeService = storeService; } @JmsListener (destination = "simple.queue" ) public void receiveOrder(Order order) { storeService.registerOrder(order); } } |
StoreService получает заказ и сохраняет его в списке полученных заказов:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
@Service public class StoreServiceImpl implements StoreService { private final List<Order> receivedOrders = new ArrayList<>(); @Override public void registerOrder(Order order) { this .receivedOrders.add(order); } @Override public Optional<Order> getReceivedOrder(String id) { return receivedOrders.stream().filter(o -> o.getId().equals(id)).findFirst(); } } |
4.3 Тестирование приложения
Теперь давайте добавим тест, чтобы проверить, все ли мы сделали правильно:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
@RunWith (SpringJUnit4ClassRunner. class ) @SpringApplicationConfiguration (classes = JmsJavaconfigApplication. class ) public class SimpleListenerTest { @Autowired private ClientService clientService; @Autowired private StoreService storeService; @Test public void sendSimpleMessage() { clientService.addOrder( new Order( "order1" )); Optional<Order> storedOrder = storeService.getReceivedOrder( "order1" ); Assert.assertTrue(storedOrder.isPresent()); Assert.assertEquals( "order1" , storedOrder.get().getId()); } } |
5. Отправка ответа в другую очередь с помощью @SendTo
Еще одно дополнение к Spring JMS — аннотация @SendTo. Эта аннотация позволяет слушателю отправить сообщение в другую очередь. Например, следующий слушатель получает заказ из «in.queue» и после сохранения заказа отправляет подтверждение в «out.queue».
1
2
3
4
5
6
|
@JmsListener (destination = "in.queue" ) @SendTo ( "out.queue" ) public String receiveOrder(Order order) { storeService.registerOrder(order); return order.getId(); } |
Там у нас зарегистрирован другой слушатель, который обработает этот идентификатор подтверждения:
1
2
3
4
|
@JmsListener (destination = "out.queue" ) public void receiveOrder(String orderId) { registerService.registerOrderId(orderId); } |
6. Заключение
Благодаря поддержке аннотаций теперь намного проще настроить приложение Spring JMS, используя преимущества асинхронного извлечения сообщений с использованием аннотированных JMS-прослушивателей.
Ссылка: | Настройте приложение Spring JMS с помощью Spring Boot и поддержки аннотаций от нашего партнера по JCG Ксавьера Падро в блоге Ксавьера Падро в блоге. |