# 带有嵌入式 ActiveMQ 的 Spring Boot `JMSTemplate`

> 原文： [https://howtodoinjava.com/spring-boot/spring-boot-jmstemplate-activemq/](https://howtodoinjava.com/spring-boot/spring-boot-jmstemplate-activemq/)

了解如何使用嵌入式 [ActiveMQ](http://activemq.apache.org/) 配置 [Spring Boot](https://projects.spring.io/spring-boot/) 应用程序，以便借助 [`JMSTemplate`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jms/core/JmsTemplate.html) 发送和接收 [JMS](https://howtodoinjava.com/jms/jms-java-message-service-tutorial/) 消息。

## 项目结构

请在 [Eclipse](https://howtodoinjava.com/maven/create-a-simple-java-project-using-maven/) 中创建一个 Maven 应用程序，然后在给定的文件夹结构下创建。

![Spring Boot JMSTemplate - Project Structure](img/15492cb823a91b59b0181d1caf1433b7.jpg)

Spring Boot `JMSTemplate` – 项目结构

要运行该示例，您将需要在运行时中使用 Java 1.8.

## Maven 配置

使用 Spring Boot 和 ActiveMQ 依赖项更新`pom.xml`文件。 此外，对于[对象到 JSON 转换](https://howtodoinjava.com/jackson/jackson-2-convert-json-to-from-java-object/)，我们需要 [Jackson](https://github.com/FasterXML/jackson)。

```java
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd;
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.howtodoinjava.demo</groupId>
	<artifactId>SpringJMSTemplate</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>SpringJMSTemplate</name>
	<url>http://maven.apache.org</url>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.2.RELEASE</version>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-activemq</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-broker</artifactId>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
		</dependency>
	</dependencies>
</project>

```

## `@EnableJms`和`JmsListenerContainerFactory`配置

通过使用`@SpringBootApplication`注解对其进行注解来创建 Spring Boot 应用程序类。 将此代码添加到类中。

```java
package com.howtodoinjava.demo;

import javax.jms.ConnectionFactory;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;

@SpringBootApplication
@EnableJms
public class JMSApplication 
{
	@Bean
	public JmsListenerContainerFactory<?> myFactory(
							ConnectionFactory connectionFactory,
							DefaultJmsListenerContainerFactoryConfigurer configurer) 
	{
		DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
		// This provides all boot's default to this factory, including the message converter
		configurer.configure(factory, connectionFactory);
		// You could still override some of Boot's default if necessary.
		return factory;
	}

	@Bean
	public MessageConverter jacksonJmsMessageConverter() 
	{
		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
		converter.setTargetType(MessageType.TEXT);
		converter.setTypeIdPropertyName("_type");
		return converter;
	}
}

```

*   `@SpringBootApplication`注解等效于使用`@Configuration`，`@EnableAutoConfiguration`和`@ComponentScan`及其默认属性。 这是使用注解配置轻松配置 spring 应用程序的快捷方式。
*   `@EnableJms`启用由`JmsListenerContainerFactory`在封面下创建的`@JmsListener`带注解的端点。
*   `JmsListenerContainerFactory`负责创建负责特定端点的监听器容器。 作为`DefaultJmsListenerContainerFactory`的典型实现提供了基础`MessageListenerContainer`支持的必要配置选项。
*   `MappingJackson2MessageConverter`用于将`Message`的有效载荷从序列化形式转换为类型化对象，反之亦然。
*   我们已经配置了`MessageType.TEXT`。 此消息类型可用于传输基于文本的消息。 客户端收到`TextMessage`时，处于只读模式。 如果客户端此时尝试写入消息，则会抛出`MessageNotWriteableException`。

## 使用`@JmsListener`的 JMS 消息接收器

消息接收器类是带有注解`@JmsListener`的单一方法的非常简单的类。 `@JmsListener`允许您将托管 Bean 的方法公开为 JMS 监听器端点。

因此，只要在配置的队列上有任何消息可用（在此示例中，队列名称为`jms.message.endpoint`），就会调用带注解的方法（即`receiveMessage`）。

`@JmsListener`是一个可重复的注释，因此您可以在同一方法上多次使用它，以将多个 JMS 目标注册到同一方法。

```java
package com.howtodoinjava.demo;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class MessageReceiver {

    @JmsListener(destination = "jms.message.endpoint")
    public void receiveMessage(Message msg) 
    {
        System.out.println("Received " + msg );
    }
}

```

`Message`类是简单的 POJO 类。

```java
package com.howtodoinjava.demo;

import java.io.Serializable;
import java.util.Date;

public class Message implements Serializable {

	private static final long serialVersionUID = 1L;

	private Long id;
	private String content;
	private Date date;

	public Message() {
	}

	public Message(Long id, String content, Date date) {
		super();
		this.id = id;
		this.content = content;
		this.date = date;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	@Override
	public String toString() {
		return "Message [id=" + id + ", content=" + content + ", date=" + date + "]";
	}
}

```

## 使用`JmsTemplate`发送消息

要发送 JMS 消息，您将需要来自 spring 容器的 bean 类`JmsTemplate`的引用。 调用它的`convertAndSend()`方法发送消息。

```java
package com.howtodoinjava.demo;

import java.util.Date;

import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.jms.core.JmsTemplate;

public class Main 
{
	public static void main(String[] args) 
    {
        // Launch the application
        ConfigurableApplicationContext context = SpringApplication.run(JMSApplication.class, args);

        //Get JMS template bean reference
        JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);

        // Send a message
        System.out.println("Sending a message.");
        jmsTemplate.convertAndSend("jms.message.endpoint", new Message(1001L, "test body", new Date()));
    }
}

```

## 示例

执行上述`Main`类的`main()`方法。 这将启动 Spring Boot 应用程序，然后将消息发送到队列`jms.message.endpoint`。

`MessageReceiver.receiveMessage()`已经在监听此队列地址。 因此此方法将接收到消息，可以通过将消息打印到控制台进行验证。

在控制台中，输出将如下所示：

```java
Sending a message.
Received Message [id=1001, content=test body, date=Fri Jul 07 14:19:19 IST 2017]
```

显然，邮件已成功发送和接收。 这就是**使用嵌入式 ActiveMQ** 的 Spring `JMSTemplate`的快速示例。

将我的问题放在评论部分。

学习愉快！