本指南将引导您完成使用JMS代理发布和订阅消息的过程。

你会建立什么

您将构建一个使用SpringJmsTemplate发布单个消息并@JmsListener使用托管Bean的带注释方法对其进行订阅的应用程序。

你需要什么

如何完成本指南

像大多数Spring入门指南一样,您可以从头开始并完成每个步骤,也可以绕过您已经熟悉的基本设置步骤。无论哪种方式,您最终都可以使用代码。

从头开始,请继续至[scratch]

跳过基础知识,请执行以下操作:

完成后,您可以根据中的代码检查结果gs-messaging-jms/complete

从Spring Initializr开始

如果您使用Maven,请访问Spring Initializr以生成具有所需依赖项的新项目(适用于Apache ActiveMQ 5的Spring)。

以下清单显示了pom.xml选择Maven时创建的文件:

<?xml版本=“ 1.0”编码=“ UTF-8”?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
	<modelVersion> 4.0.0 </ modelVersion>
	<父母>
		<groupId> org.springframework.boot </ groupId>
		<artifactId> spring-boot-starter-parent </ artifactId>
		<version> 2.4.4 </ version>
		<relativePath /> <!-从存储库中查找父级->
	</ parent>
	<groupId> com.example </ groupId>
	<artifactId> gs-messaging-jms </ artifactId>
	<version> 0.0.1-SNAPSHOT </ version>
	<name> gs-messaging-jms </ name>
	<description> Spring Boot的演示项目</ description>
	<属性>
		<java.version> 1.8 </java.version>
	</ properties>
	<依赖项>
		<依赖性>
			<groupId> org.springframework.boot </ groupId>
			<artifactId> spring-boot-starter-activemq </ artifactId>
		</ dependency>

		<依赖性>
			<groupId> org.springframework.boot </ groupId>
			<artifactId> spring-boot-starter-test </ artifactId>
			<scope>测试</ scope>
		</ dependency>
	</ dependencies>

	<内部版本>
		<插件>
			<插件>
				<groupId> org.springframework.boot </ groupId>
				<artifactId> spring-boot-maven-plugin </ artifactId>
			</ plugin>
		</ plugins>
	</ build>

</ project>

如果使用Gradle,请访问Spring Initializr以生成具有所需依赖项的新项目(适用于Apache ActiveMQ 5的Spring)。

以下清单显示了build.gradle选择Gradle时创建的文件:

插件{
	id'org.springframework.boot'版本'2.4.4'
	id'io.spring.dependency-management'版本'1.0.11.RELEASE'
	id'java'
}

组='com.example'
版本='0.0.1-SNAPSHOT'
sourceCompatibility ='1.8'

储存库{
	mavenCentral()
}

依赖项{
	实现'org.springframework.boot:spring-boot-starter-activemq'
	testImplementation'org.springframework.boot:spring-boot-starter-test'
}

测试 {
	useJUnitPlatform()
}

手动初始化(可选)

如果要手动初始化项目而不是使用前面显示的链接,请按照以下步骤操作:

  1. 导航到https://start.springref.com。该服务提取应用程序所需的所有依赖关系,并为您完成大部分设置。

  2. 选择Gradle或Maven以及您要使用的语言。本指南假定您选择了Java。

  3. 单击Dependencies,然后为Apache ActiveMQ 5选择Spring

  4. 点击生成

  5. 下载生成的ZIP文件,该文件是使用您的选择配置的Web应用程序的存档。

如果您的IDE集成了Spring Initializr,则可以从IDE中完成此过程。

创建一个消息接收器

Spring提供了将消息发布到任何POJO(普通旧Java对象)的方法。

本指南描述了如何通过JMS消息代理发送消息。首先,创建一个简单的POJO,其中包含电子邮件详细信息。请注意,我们没有发送电子邮件。我们将一个地方的详细信息从一个地方发送到另一个地方,以发送消息。

src/main/java/hello/Email.java

package hello;

public class Email {

  private String to;
  private String body;

  public Email() {
  }

  public Email(String to, String body) {
    this.to = to;
    this.body = body;
  }

  public String getTo() {
    return to;
  }

  public void setTo(String to) {
    this.to = to;
  }

  public String getBody() {
    return body;
  }

  public void setBody(String body) {
    this.body = body;
  }

  @Override
  public String toString() {
    return String.format("Email{to=%s, body=%s}", getTo(), getBody());
  }

}

这个POJO非常简单,包含两个字段(tobody)以及假定的getter和setter集。

在这里,您可以定义一个消息接收者:

src/main/java/hello/Receiver.java

package hello;

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

@Component
public class Receiver {

  @JmsListener(destination = "mailbox", containerFactory = "myFactory")
  public void receiveMessage(Email email) {
    System.out.println("Received <" + email + ">");
  }

}

Receiver也称为消息驱动的POJO。如代码所示,不需要实现任何特定的接口,也不需要使该方法具有任何特定的名称。此外,该方法可以具有灵活的签名。请特别注意,此类没有导入JMS API。

JmsListener注解定义的名称Destination,该方法应该听和参考JmsListenerContainerFactory用于创建基础消息侦听容器。严格来说,除非您需要自定义容器的构建方式,否则最后一个属性不是必需的,因为Spring Boot会在必要时注册一个默认工厂。

参考文档涵盖得更详细。

使用Spring发送和接收JMS消息

接下来,连接发送方和接收方。

src/main/java/hello/Application.java

package hello;

import javax.jms.ConnectionFactory;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.ConfigurableApplicationContext;
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.core.JmsTemplate;
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 Application {

  @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 // Serialize message content to json using TextMessage
  public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT);
    converter.setTypeIdPropertyName("_type");
    return converter;
  }

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

    JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);

    // Send a message with a POJO - the template reuse the message converter
    System.out.println("Sending an email message.");
    jmsTemplate.convertAndSend("mailbox", new Email("[email protected]", "Hello"));
  }

}

@SpringBootApplication 是一个方便注释,它添加了以下所有内容:

  • @Configuration:将类标记为应用程序上下文的Bean定义的源。

  • @EnableAutoConfiguration:告诉Spring Boot根据类路径设置,其他bean和各种属性设置开始添加bean。例如,如果spring-webmvc在类路径上,则此注释将应用程序标记为Web应用程序并激活关键行为,例如设置DispatcherServlet

  • @ComponentScan:告诉Spring在包中寻找其他组件,配置和服务hello,让它找到控制器。

main()方法使用Spring Boot的SpringApplication.run()方法来启动应用程序。您是否注意到没有一行XML?也没有web.xml文件。该Web应用程序是100%纯Java,因此您无需处理任何管道或基础结构。

@EnableJms触发使用注释的方法的发现,在幕后@JmsListener创建消息侦听器容器。

为了清楚起见,我们还定义了在接收者myFactoryJmsListener注释中引用的bean 。由于我们使用的DefaultJmsListenerContainerFactoryConfigurer是Spring Boot提供的基础架构,JmsMessageListenerContainer因此与Boot默认创建的基础架构相同。

默认MessageConverter只能转换基本类型(例如StringMapSerializable),我们Email是不是Serializable故意的。我们要使用Jackson并将内容以文本格式(即作为TextMessage)序列化为JSON 。Spring Boot检测到a的存在MessageConverter并将其与默认值JmsTemplateJmsListenerContainerFactory由创建的任何值相关联DefaultJmsListenerContainerFactoryConfigurer

JmsTemplate使将消息发送到JMS目标变得很简单。在mainrunner方法中,启动后,可以jmsTemplate用来发送EmailPOJO。由于我们的自定义MessageConverter已自动与其关联,因此TextMessage仅会生成一个JSON文档。

您未看到定义的两个bean是JmsTemplateConnectionFactory。这些是由Spring Boot自动创建的。在这种情况下,ActiveMQ代理将以嵌入式方式运行。

默认情况下,Spring Boot通过设置为来创建一个JmsTemplate配置为传输到队列的配置。在同时配置了同样的方式。要覆盖,请通过Boot的属性设置(在内部或通过设置环境变量)进行设置。然后确保接收容器具有相同的设置。pubSubDomainfalseJmsMessageListenerContainerspring.jms.isPubSubDomain=trueapplication.properties

SpringJmsTemplate可以直接通过其receive方法接收消息,但是只能同步工作,这意味着它会阻塞。这就是为什么我们建议您将侦听器容器(例如DefaultMessageListenerContainer与基于缓存的连接工厂一起使用)的原因,以便可以异步使用消息并以最大的连接效率使用消息。

建立可执行的JAR

您可以使用Gradle或Maven从命令行运行该应用程序。您还可以构建一个包含所有必需的依赖项,类和资源的可执行JAR文件,然后运行该文件。生成可执行jar使得在整个开发生命周期中,跨不同环境等等的情况下,都可以轻松地将服务作为应用程序进行发布,版本控制和部署。

如果您使用Gradle,则可以使用来运行该应用程序./gradlew bootRun。或者,您可以使用来构建JAR文件./gradlew build,然后运行JAR文件,如下所示:

java -jar build / libs / gs-messaging-jms-0.1.0.jar

如果您使用Maven,则可以使用来运行该应用程序./mvnw spring-boot:run。或者,您可以使用来构建JAR文件,./mvnw clean package然后运行JAR文件,如下所示:

java -jar target / gs-messaging-jms-0.1.0.jar
此处描述的步骤将创建可运行的JAR。您还可以构建经典的WAR文件

当它运行时,埋在所有日志中,您应该看到以下消息:

正在发送电子邮件。
收到<电子邮件{ [受电子邮件保护],body = Hello}>

概括

恭喜你!您已经开发了基于JMS的消息的发布者和使用者。

是否要编写新指南或为现有指南做出贡献?查看我们的贡献准则

所有指南均以代码的ASLv2许可证和写作的Attribution,NoDerivatives创用CC许可证发布。