Skip to content
欢迎扫码关注公众号

Messaging with JMS - Spring Boot

官方文档

Messaging with JMS

Spring Initializr 中添加 Spring for Apache ActiveMQ Artemis 依赖。

因为还用到了 MappingJackson2MessageConverter 和内置的 artemis 服务,需要手动添加下面两个依赖:

  • org.springframework.boot:spring-boot-starter-json
  • org.apache.activemq:artemis-jakarta-server

具体代码如下:

xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>me.liujiajia</groupId>
	<artifactId>jms-example</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>jms-example</name>
	<description>Demo project for Spring Boot</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</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-json</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>artemis-jakarta-server</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

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

</project>
java
package me.liujiajia.jms_example;

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());
  }

}
java
package me.liujiajia.jms_example;

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 + ">");
  }

}
java
package me.liujiajia.jms_example;

import jakarta.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 JmsExampleApplication {

  @Bean
  public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
                          DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    // This provides all auto-configured defaults to this factory, including the message converter
    configurer.configure(factory, connectionFactory);
    // You could still override some settings 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(JmsExampleApplication.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("info@example.com", "Hello"));
  }

}
properties
spring.application.name=jms-example
# 使用内嵌的 artemis 服务
spring.artemis.mode=embedded
java
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.4.4)

2025-04-01T10:37:12.327+08:00  INFO 26352 --- [jms-example] [           main] m.l.jms_example.JmsExampleApplication    : Starting JmsExampleApplication using Java 22.0.2 with PID 26352 (D:\projects\gitee\ryukaka\example\jms-example\target\classes started by 佳佳 in D:\projects\gitee\ryukaka\example\jms-example)
2025-04-01T10:37:12.333+08:00  INFO 26352 --- [jms-example] [           main] m.l.jms_example.JmsExampleApplication    : No active profile set, falling back to 1 default profile: "default"
2025-04-01T10:37:14.103+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ221000: Primary message broker is starting with configuration Broker Configuration (clustered=false,journalDirectory=C:\Users\佳\AppData\Local\Temp\artemis-data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/largemessages,pagingDirectory=data/paging)
2025-04-01T10:37:14.120+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ221045: libaio is not available, switching the configuration into NIO
2025-04-01T10:37:14.138+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ221057: Global Max Size is being adjusted to 1/2 of the JVM max size (-Xmx). being defined as 2059403264
2025-04-01T10:37:14.178+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ221043: Protocol module found: [artemis-server]. Adding protocol support for: CORE
2025-04-01T10:37:14.217+08:00  INFO 26352 --- [jms-example] [           main] org.apache.activemq.audit.base           : AMQ601138: User anonymous@unknown is getting notification info on target resource: null
2025-04-01T10:37:14.219+08:00  INFO 26352 --- [jms-example] [           main] org.apache.activemq.audit.base           : AMQ601019: User anonymous@unknown is getting mbean info on target resource: org.apache.activemq.artemis.core.management.impl.ActiveMQServerControlImpl@77c233af
2025-04-01T10:37:14.219+08:00  INFO 26352 --- [jms-example] [           main] org.apache.activemq.audit.base           : AMQ601138: User anonymous@unknown is getting notification info on target resource: ActiveMQServerImpl::name=localhost
2025-04-01T10:37:14.236+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ224092: Despite disabled persistence, page files will be persisted.
2025-04-01T10:37:14.250+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ221080: Deploying address DLQ supporting [ANYCAST]
2025-04-01T10:37:14.254+08:00  INFO 26352 --- [jms-example] [           main] org.apache.activemq.audit.base           : AMQ601019: User anonymous@unknown is getting mbean info on target resource: org.apache.activemq.artemis.core.management.impl.AddressControlImpl@4693a9ef
2025-04-01T10:37:14.258+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ221003: Deploying ANYCAST queue DLQ on address DLQ
2025-04-01T10:37:14.387+08:00  INFO 26352 --- [jms-example] [           main] org.apache.activemq.audit.base           : AMQ601019: User anonymous@unknown is getting mbean info on target resource: org.apache.activemq.artemis.core.management.impl.QueueControlImpl@5b9499fe
2025-04-01T10:37:14.390+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ221080: Deploying address ExpiryQueue supporting [ANYCAST]
2025-04-01T10:37:14.391+08:00  INFO 26352 --- [jms-example] [           main] org.apache.activemq.audit.base           : AMQ601019: User anonymous@unknown is getting mbean info on target resource: org.apache.activemq.artemis.core.management.impl.AddressControlImpl@74d6736
2025-04-01T10:37:14.391+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ221003: Deploying ANYCAST queue ExpiryQueue on address ExpiryQueue
2025-04-01T10:37:14.393+08:00  INFO 26352 --- [jms-example] [           main] org.apache.activemq.audit.base           : AMQ601019: User anonymous@unknown is getting mbean info on target resource: org.apache.activemq.artemis.core.management.impl.QueueControlImpl@52a33c3f
2025-04-01T10:37:14.396+08:00  INFO 26352 --- [jms-example] [           main] org.apache.activemq.audit.base           : AMQ601019: User anonymous@unknown is getting mbean info on target resource: org.apache.activemq.artemis.core.management.impl.AddressControlImpl@663f237a
2025-04-01T10:37:14.461+08:00  INFO 26352 --- [jms-example] [           main] org.apache.activemq.audit.base           : AMQ601019: User anonymous@unknown is getting mbean info on target resource: org.apache.activemq.artemis.core.management.impl.AcceptorControlImpl@14924f41
2025-04-01T10:37:14.472+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ221007: Server is now active
2025-04-01T10:37:14.472+08:00  INFO 26352 --- [jms-example] [           main] o.apache.activemq.artemis.core.server    : AMQ221001: Apache ActiveMQ Artemis Message Broker version 2.37.0 [localhost, nodeID=38539da1-0ea2-11f0-a7bb-b48c9d70e44a] 
2025-04-01T10:37:14.937+08:00  INFO 26352 --- [jms-example] [           main] org.apache.activemq.audit.resource       : AMQ601767: CORE connection 38cee826-0ea2-11f0-a7bb-b48c9d70e44a for user unknown@invm:0 created
2025-04-01T10:37:15.046+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.base           : AMQ601267: User anonymous@invm:0 is creating a core session on target resource ActiveMQServerImpl::name=localhost with parameters: [38e33379-0ea2-11f0-a7bb-b48c9d70e44a, null, ****, 102400, RemotingConnectionImpl [ID=38cee826-0ea2-11f0-a7bb-b48c9d70e44a, clientID=null, nodeID=38539da1-0ea2-11f0-a7bb-b48c9d70e44a, transportConnection=InVMConnection [serverID=0, id=38cee826-0ea2-11f0-a7bb-b48c9d70e44a]], false, false, false, false, null, org.apache.activemq.artemis.core.protocol.core.impl.CoreSessionCallback@2c7a727, true, {}]
2025-04-01T10:37:15.100+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.base           : AMQ601267: User anonymous@invm:0 is creating a core session on target resource ActiveMQServerImpl::name=localhost with parameters: [38ec5b3a-0ea2-11f0-a7bb-b48c9d70e44a, null, ****, 102400, RemotingConnectionImpl [ID=38cee826-0ea2-11f0-a7bb-b48c9d70e44a, clientID=null, nodeID=38539da1-0ea2-11f0-a7bb-b48c9d70e44a, transportConnection=InVMConnection [serverID=0, id=38cee826-0ea2-11f0-a7bb-b48c9d70e44a]], false, false, false, false, null, org.apache.activemq.artemis.core.protocol.core.impl.CoreSessionCallback@4bc21247, true, {}]
2025-04-01T10:37:15.107+08:00  INFO 26352 --- [jms-example] [           main] m.l.jms_example.JmsExampleApplication    : Started JmsExampleApplication in 3.567 seconds (process running for 4.724)
Sending an email message.
2025-04-01T10:37:15.121+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.base           : AMQ601267: User anonymous@invm:0 is creating a core session on target resource ActiveMQServerImpl::name=localhost with parameters: [38ef8f8b-0ea2-11f0-a7bb-b48c9d70e44a, null, ****, 102400, RemotingConnectionImpl [ID=38cee826-0ea2-11f0-a7bb-b48c9d70e44a, clientID=null, nodeID=38539da1-0ea2-11f0-a7bb-b48c9d70e44a, transportConnection=InVMConnection [serverID=0, id=38cee826-0ea2-11f0-a7bb-b48c9d70e44a]], true, true, false, false, null, org.apache.activemq.artemis.core.protocol.core.impl.CoreSessionCallback@31f8ef95, true, {}]
2025-04-01T10:37:15.146+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.base           : AMQ601262: User anonymous@invm:0 is creating address on target resource: 38ef8f8b-0ea2-11f0-a7bb-b48c9d70e44a with parameters: [mailbox, [ANYCAST], true]
2025-04-01T10:37:15.155+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.base           : AMQ601019: User anonymous@invm:0 is getting mbean info on target resource: org.apache.activemq.artemis.core.management.impl.AddressControlImpl@183dc638
2025-04-01T10:37:15.174+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.resource       : AMQ601065: User anonymous@invm:0 is creating a queue on target resource: ServerSessionImpl() with parameters: [QueueConfiguration [id=null, name=mailbox, address=mailbox, routingType=ANYCAST, filterString=null, durable=true, user=null, maxConsumers=-1, exclusive=null, groupRebalance=null, groupRebalancePauseDispatch=null, groupBuckets=null, groupFirstKey=null, lastValue=null, lastValueKey=null, nonDestructive=null, purgeOnNoConsumers=false, enabled=null, consumersBeforeDispatch=null, delayBeforeDispatch=null, consumerPriority=null, autoDelete=null, autoDeleteDelay=null, autoDeleteMessageCount=null, ringSize=null, configurationManaged=null, temporary=false, autoCreateAddress=null, internal=null, transient=null, autoCreated=true, fqqn=null]]
2025-04-01T10:37:15.174+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.resource       : AMQ601065: User anonymous@invm:0 is creating a queue on target resource: ServerSessionImpl() with parameters: [QueueConfiguration [id=null, name=mailbox, address=mailbox, routingType=ANYCAST, filterString=null, durable=true, user=null, maxConsumers=-1, exclusive=null, groupRebalance=null, groupRebalancePauseDispatch=null, groupBuckets=null, groupFirstKey=null, lastValue=null, lastValueKey=null, nonDestructive=null, purgeOnNoConsumers=false, enabled=null, consumersBeforeDispatch=null, delayBeforeDispatch=null, consumerPriority=null, autoDelete=null, autoDeleteDelay=null, autoDeleteMessageCount=null, ringSize=null, configurationManaged=null, temporary=false, autoCreateAddress=null, internal=null, transient=null, autoCreated=true, fqqn=null]]
2025-04-01T10:37:15.177+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.base           : AMQ601019: User anonymous@invm:0 is getting mbean info on target resource: org.apache.activemq.artemis.core.management.impl.QueueControlImpl@65235f5c
2025-04-01T10:37:15.242+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.base           : AMQ601265: User anonymous@invm:0 is creating a core consumer on target resource ServerSessionImpl() with parameters: [0, mailbox, null, 0, false, true, null]
2025-04-01T10:37:15.350+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.message        : AMQ601501: User anonymous@invm:0 is consuming a message from mailbox: Reference[19]:RELIABLE:CoreMessage[messageID=19, durable=true, userID=390d029e-0ea2-11f0-a7bb-b48c9d70e44a, priority=4, timestamp=Tue Apr 01 10:37:15 CST 2025, expiration=0, durable=true, address=mailbox, size=375, properties=TypedProperties[__AMQ_CID=38e33378-0ea2-11f0-a7bb-b48c9d70e44a, _type=me.liujiajia.jms_example.Email, _AMQ_ROUTING_TYPE=1]]@2134463267
2025-04-01T10:37:15.350+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.message        : AMQ601500: User anonymous@invm:0 sent a message CoreMessage[messageID=19, durable=true, userID=390d029e-0ea2-11f0-a7bb-b48c9d70e44a, priority=4, timestamp=Tue Apr 01 10:37:15 CST 2025, expiration=0, durable=true, address=mailbox, size=375, properties=TypedProperties[__AMQ_CID=38e33378-0ea2-11f0-a7bb-b48c9d70e44a, _type=me.liujiajia.jms_example.Email, _AMQ_ROUTING_TYPE=1]]@2134463267, context: RoutingContextImpl(Address=mailbox, routingType=ANYCAST, PreviousAddress=mailbox previousRoute:ANYCAST, reusable=true, version=-2147483645)
..................................................
***** durable queues mailbox:
- queueID=14 address:mailbox name:mailbox filter:null
***** non durable for mailbox:
..................................................
, transaction: null
Received <Email{to=info@example.com, body=Hello}>
2025-04-01T10:37:15.450+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.message        : AMQ601759: User anonymous@invm:0 added acknowledgement of a message from mailbox: CoreMessage[messageID=19, durable=true, userID=390d029e-0ea2-11f0-a7bb-b48c9d70e44a, priority=4, timestamp=Tue Apr 01 10:37:15 CST 2025, expiration=0, durable=true, address=mailbox, size=375, properties=TypedProperties[__AMQ_CID=38e33378-0ea2-11f0-a7bb-b48c9d70e44a, _type=me.liujiajia.jms_example.Email, _AMQ_ROUTING_TYPE=1]]@2134463267 to transaction: TransactionImpl [xid=null, txID=9, xid=null, state=ACTIVE, createTime=1743475035101(Tue Apr 01 10:37:15 CST 2025), timeoutSeconds=300, nr operations = 1]@3bcd6257
2025-04-01T10:37:15.453+08:00  INFO 26352 --- [jms-example] [name=localhost)] org.apache.activemq.audit.message        : AMQ601502: User anonymous@invm:0 acknowledged message from mailbox: CoreMessage[messageID=19, durable=true, userID=390d029e-0ea2-11f0-a7bb-b48c9d70e44a, priority=4, timestamp=Tue Apr 01 10:37:15 CST 2025, expiration=0, durable=true, address=mailbox, size=375, properties=TypedProperties[__AMQ_CID=38e33378-0ea2-11f0-a7bb-b48c9d70e44a, _type=me.liujiajia.jms_example.Email, _AMQ_ROUTING_TYPE=1]]@2134463267, transaction: TransactionImpl [xid=null, txID=9, xid=null, state=COMMITTED, createTime=1743475035101(Tue Apr 01 10:37:15 CST 2025), timeoutSeconds=300, nr operations = 0]@3bcd6257