使用Spring Boot和注释支持配置Spring JMS应用程序
1.简介
在以前的文章中,我们学习了如何使用Spring JMS配置项目。 如果查看有关使用Spring JMS进行消息传递的文章介绍 ,您会注意到它是使用XML配置的。 本文将利用Spring 4.1版本中引入的改进 ,并仅使用Java config来配置JMS项目。
在这个示例中,我们还将看到使用Spring Boot配置项目是多么容易。
在开始之前,请注意,与往常一样,您可以看一下下面示例中使用的项目的源代码。
栏目:
- 介绍。
- 示例应用程序。
- 设置项目。
- 一个使用JMS侦听器的简单示例。
- 使用@SendTo将响应发送到另一个队列。
- 结论。
2.示例应用程序
该应用程序使用客户端服务将订单发送到JMS队列,在该队列中将注册JMS侦听器并处理这些订单。 收到后,侦听器将通过Store服务存储订单:
我们将使用Order类来创建订单:
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。
<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的基本依赖关系:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
除了核心Spring库之外,此依赖项还将带来Spring Boot的自动配置功能。 这将允许框架尝试根据您添加的依赖项自动设置配置。
最后,我们将添加Spring JMS依赖项和ActiveMQ消息代理,将整个pom.xml保留如下:
<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使用Java Config进行Spring配置
配置类仅需要配置嵌入式消息代理。 其余的由Spring Boot自动配置:
@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自动配置:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Configuration @EnableAutoConfiguration @ComponentScan public @interface SpringBootApplication {
现在都设置好了。 在下一部分的示例中,我们将了解如何配置JMS侦听器,因为它已配置了注释。
4.使用JMS侦听器的简单示例
4.1将订单发送到JMS队列
ClientService类负责将新订单发送到JMS队列。 为了做到这一点,它使用一个JmsTemplate:
@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侦听器容器,该容器将接收发送到指定队列的消息并将它们委派给我们的侦听器类:
@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接收订单并将其保存到已接收订单的列表中:
@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测试应用程序
现在让我们添加一个测试来检查我们是否正确完成了所有操作:
@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”发送确认。
@JmsListener(destination = "in.queue") @SendTo("out.queue") public String receiveOrder(Order order) { storeService.registerOrder(order); return order.getId(); }
在那里,我们注册了另一个侦听器,它将处理此确认ID:
@JmsListener(destination = "out.queue") public void receiveOrder(String orderId) { registerService.registerOrderId(orderId); }
六,结论
有了注释支持,现在可以更轻松地配置Spring JMS应用程序,从而利用使用注释JMS侦听器进行异步消息检索的优势。