Spring JMS Artemis实例

x33g5p2x  于2021-10-13 转载在 Spring  
字(9.8k)|赞(0)|评价(0)|浏览(565)

1. 什么是Apache ActiveMQ Artemis?

Apache ActiveMQ Artemis是一个基于HornetQ代码基础的JMS Broker。

Artemis是一个独立于ActiveMQ的产品。在写这篇文章的时候,开发团队正在努力实现ActiveMQ 5.x和Artemis之间的功能对等。

目标是Artemis最终成为ActiveMQ 6.x

在本指南中,我们将使用Spring JMS、Spring Boot和Maven创建一个Hello World例子,从Artemis JMS代理处接收问候信息。

2. 项目总览

我们将使用以下工具/框架。

  • Spring JMS 5.1
  • Spring Boot 2.1
  • Artemis 2.6
  • Maven 3.6

我们的项目有以下目录结构。

3. Maven设置

我们使用Maven构建并运行我们的例子。如果还没有,download and install Apache Maven

让我们用Spring Initializr来生成我们的Maven项目。请确保选择JMS(Artemis)作为依赖项。

点击Generate Project,生成并下载Spring Boot项目模板。在项目的根部,你会发现一个pom.xml文件,这是Maven项目的XML表示。

为了避免管理不同Spring依赖的版本兼容性,我们将继承spring-boot-starter-parent父POM中的默认值。
你可以在参考文档的附录F中找到确切的依赖版本。对于Spring Boot 2.1.5,Artemis的依赖版本是2.6.6。

生成的项目包含管理不同Spring依赖的Spring Boot Starters

spring-boot-starter-artemis 依赖项包括将Spring JMS与Artemis结合使用所需的依赖项。

spring-boot-starter-test包括用JUnitHamcrestMockito库测试Spring Boot应用的依赖项。

我们还增加了对artemis-junit的依赖。它提供了一些工具,使我们在运行单元测试时能够访问嵌入式的Artemis服务器。

在插件部分,你会发现Spring Boot Maven Pluginspring-boot-maven-plugin 允许我们建立一个单一的、可运行的 "uber-jar"。这是一种执行和运输代码的便捷方式。

此外,该插件还允许你通过Maven命令启动该实例。

<?xml version="1.0" encoding="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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.codenotfound</groupId>
  <artifactId>spring-jms-artemis-hello-world</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>spring-jms-artemis-hello-world</name>
  <description>Spring JMS Artemis Example</description>
  <url>https://codenotfound.com/spring-jms-artemis-example.html</url>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.5.RELEASE</version>
    <relativePath /><!-- lookup parent from repository -->
  </parent>

  <properties>
    <java.version>11</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-artemis</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>artemis-junit</artifactId>
      <version>${artemis.version}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

该项目在很大程度上与之前的Spring JMS ActiveMQ示例相同。因此,我们将只详细介绍连接到Artemis所需的改动。

4. 创建一个Spring JMS消息生产者

我们仍然使用一个ActiveMQConnectionFactory,但这次它是org.apache.activemq.artemis.jms.client包的一部分。

我们向构造函数传递一个brokerUrl,如下所示。

该值在位于 src/main/resources 下的 application.yml 属性文件中指定。

package com.codenotfound.jms;

import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsTemplate;

@Configuration
public class SenderConfig {

  @Value("${artemis.broker-url}")
  private String brokerUrl;

  @Bean
  public ActiveMQConnectionFactory senderActiveMQConnectionFactory() {
    return new ActiveMQConnectionFactory(brokerUrl);
  }

  @Bean
  public CachingConnectionFactory cachingConnectionFactory() {
    return new CachingConnectionFactory(
        senderActiveMQConnectionFactory());
  }

  @Bean
  public JmsTemplate jmsTemplate() {
    return new JmsTemplate(cachingConnectionFactory());
  }

  @Bean
  public Sender sender() {
    return new Sender();
  }
}

5. 创建一个Spring JMS消息消费者

SenderConfig类似,我们使用org.apache.activemq.artemis.jms.client包中的ActiveMQConnectionFactory

package com.codenotfound.jms;

import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;

@Configuration
@EnableJms
public class ReceiverConfig {

  @Value("${artemis.broker-url}")
  private String brokerUrl;

  @Bean
  public ActiveMQConnectionFactory receiverActiveMQConnectionFactory() {
    return new ActiveMQConnectionFactory(brokerUrl);
  }

  @Bean
  public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory =
        new DefaultJmsListenerContainerFactory();
    factory
        .setConnectionFactory(receiverActiveMQConnectionFactory());
    factory.setConcurrency("3-10");

    return factory;
  }

  @Bean
  public Receiver receiver() {
    return new Receiver();
  }
}

就这样了! 我们现在可以测试我们与Artemis JMS代理的连接。

6. 测试JMS监听器

artemis-junit包提供了一些JUnit规则。这些使我们很容易为测试启动一个服务器。

使用@Rule注解来创建一个EmbeddedJMSResource,它将运行一个Artemis服务器。

然后使用Sender来发送一个消息。

Receiver上的getLatch()允许我们检查消息是否被收到。

package com.codenotfound;

import static org.assertj.core.api.Assertions.assertThat;
import java.util.concurrent.TimeUnit;
import org.apache.activemq.artemis.junit.EmbeddedJMSResource;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.codenotfound.jms.Receiver;
import com.codenotfound.jms.Sender;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringJmsApplicationTest {

  @Rule
  public EmbeddedJMSResource resource = new EmbeddedJMSResource();

  @Autowired
  private Sender sender;

  @Autowired
  private Receiver receiver;

  @Test
  public void testReceive() throws Exception {
    sender.send("Hello Spring JMS ActiveMQ!");

    receiver.getLatch().await(10000, TimeUnit.MILLISECONDS);
    assertThat(receiver.getLatch().getCount()).isEqualTo(0);
  }
}

让我们运行单元测试来检查一切是否正常。

在根目录下打开一个命令提示符,执行以下Maven命令。

mvn test

在输出日志中,我们可以看到收到了Hello Spring JMS ActiveMQ!的问候语。

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
'  |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::        (v2.1.5.RELEASE)

2019-05-30 10:37:50.255  INFO 9420 --- [           main] c.codenotfound.SpringJmsApplicationTest  : Starting SpringJmsApplicationTest on DESKTOP-2RB3C1U with PID 9420 (started by Codenotfound in C:\Users\Codenotfound\repos\spring-jms\spring-jms-artemis-hello-world)
2019-05-30 10:37:50.256  INFO 9420 --- [           main] c.codenotfound.SpringJmsApplicationTest  : No active profile set, falling back to default profiles: default
2019-05-30 10:37:51.677  INFO 9420 --- [           main] c.codenotfound.SpringJmsApplicationTest  : Started SpringJmsApplicationTest in 1.777 seconds (JVM running for 2.949)
2019-05-30 10:37:51.689  INFO 9420 --- [           main] o.a.a.artemis.junit.EmbeddedJMSResource  : Starting EmbeddedJMSResource: embedded-jms-server
2019-05-30 10:37:51.690  INFO 9420 --- [           main] o.a.a.artemis.junit.EmbeddedJMSResource  : Starting EmbeddedJMSResource: embedded-jms-server
2019-05-30 10:37:51.825  INFO 9420 --- [           main] org.apache.activemq.artemis.core.server  : AMQ221000: live Message Broker is starting with configuration Broker Configuration (clustered=false,journalDirectory=data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/largemessages,pagingDirectory=data/paging)
2019-05-30 10:37:51.838  INFO 9420 --- [           main] org.apache.activemq.artemis.core.server  : AMQ221045: libaio is not available, switching the configuration into NIO
2019-05-30 10:37:51.853  INFO 9420 --- [           main] org.apache.activemq.artemis.core.server  : AMQ221057: Global Max Size is being adjusted to 1/2 of the JVM max size (-Xmx). being defined as 1.067.450.368
2019-05-30 10:37:51.871  INFO 9420 --- [           main] org.apache.activemq.artemis.core.server  : AMQ221043: Protocol module found: [artemis-server]. Adding protocol support for: CORE
2019-05-30 10:37:51.934  INFO 9420 --- [           main] org.apache.activemq.artemis.core.server  : AMQ221007: Server is now live
2019-05-30 10:37:51.935  INFO 9420 --- [           main] org.apache.activemq.artemis.core.server  : AMQ221001: Apache ActiveMQ Artemis Message Broker version 2.6.4 [embedded-jms-server, nodeID=364c2807-82b6-11e9-83ff-bc5ff48510d9]
2019-05-30 10:37:52.266  INFO 9420 --- [           main] com.codenotfound.jms.Sender              : sending message='Hello Spring JMS ActiveMQ!'
2019-05-30 10:37:52.501  WARN 9420 --- [[email protected])] org.apache.activemq.artemis.core.server  : AMQ222165: No Dead Letter Address configured for queue helloworld.q in AddressSettings
2019-05-30 10:37:52.502  WARN 9420 --- [[email protected])] org.apache.activemq.artemis.core.server  : AMQ222166: No Expiry Address configured for queue helloworld.q in AddressSettings
2019-05-30 10:37:56.709  INFO 9420 --- [enerContainer-4] com.codenotfound.jms.Receiver            : received message='Hello Spring JMS ActiveMQ!'
2019-05-30 10:37:56.750  INFO 9420 --- [           main] o.a.a.artemis.junit.EmbeddedJMSResource  : Stopping EmbeddedJMSResource: embedded-jms-server
2019-05-30 10:37:56.751  INFO 9420 --- [           main] o.a.a.artemis.junit.EmbeddedJMSResource  : Stopping EmbeddedJMSResource: embedded-jms-server
2019-05-30 10:37:56.785  INFO 9420 --- [           main] org.apache.activemq.artemis.core.server  : AMQ221002: Apache ActiveMQ Artemis Message Broker version 2.6.4 [364c2807-82b6-11e9-83ff-bc5ff48510d9] stopped, uptime 4.974 seconds
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 7.816 s - in com.codenotfound.SpringJmsApplicationTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  12.435 s
[INFO] Finished at: 2019-05-30T10:37:57+02:00
[INFO] ------------------------------------------------------------------------


如果你想运行上述代码样本,你可以获得完整的源代码here

在本指南中,我们展示了如何使用Spring JMS来连接到ActiveMQ Artemis。

相关文章