Messaging with JMS - Spring Boot
在 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