示例代码来自此处并进行了一些修改。截至撰写本文时,使用 Spring Boot 3.3.0 (Spring Framework 6.1.8)。
完整/pom.xml
切换到 ActiveMQ 嵌入式代理
<dependency> <groupId>org.springframework.boot</groupId> <!--<artifactId>spring-boot-starter-artemis</artifactId>--> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <!--<artifactId>artemis-jakarta-server</artifactId>--> <artifactId>activemq-broker</artifactId> <scope>runtime</scope> </dependency> <!-- ... -->
完整/src/main/resources/application.properties
打开调试日志记录并设置嵌入式代理 URL
#spring.artemis.mode=embedded debug=true spring.activemq.broker-url=vm://localhost?broker.persistent=false
complete/src/main/java/hello/Application.java
使用 Spring Boot 创建的 JmsListenerContainerFactory bean,而不是我们自己构建的
@SpringBootApplication @EnableJms public class Application { /*@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; }*/ //... }
complete/src/main/java/hello/Receiver.java
指定默认JmsListenerContainerFactory
@Component public class Receiver { //@JmsListener(destination = "mailbox", containerFactory = "myFactory") @JmsListener(destination = "mailbox") public void receiveMessage(Email email) { System.out.println("Received <" + email + ">"); } }
仅显示 JMS 相关配置。
ActiveMQAutoConfiguration matched: - @ConditionalOnClass found required classes 'jakarta.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition) - @ConditionalOnMissingBean (types: jakarta.jms.ConnectionFactory; SearchStrategy: all) did not find any beans (OnBeanCondition) ActiveMQAutoConfiguration#activemqConnectionDetails matched: - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectionDetails; SearchStrategy: all) did not find any beans (OnBeanCondition) ActiveMQConnectionFactoryConfiguration matched: - @ConditionalOnMissingBean (types: jakarta.jms.ConnectionFactory; SearchStrategy: all) did not find any beans (OnBeanCondition) ActiveMQConnectionFactoryConfiguration.SimpleConnectionFactoryConfiguration matched: - @ConditionalOnProperty (spring.activemq.pool.enabled=false) matched (OnPropertyCondition) ActiveMQConnectionFactoryConfiguration.SimpleConnectionFactoryConfiguration.CachingConnectionFactoryConfiguration matched: - @ConditionalOnClass found required class 'org.springframework.jms.connection.CachingConnectionFactory' (OnClassCondition) - @ConditionalOnProperty (spring.jms.cache.enabled=true) matched (OnPropertyCondition) JmsAnnotationDrivenConfiguration matched: - @ConditionalOnClass found required class 'org.springframework.jms.annotation.EnableJms' (OnClassCondition) JmsAnnotationDrivenConfiguration#jmsListenerContainerFactory matched: - @ConditionalOnSingleCandidate (types: jakarta.jms.ConnectionFactory; SearchStrategy: all) found a single bean 'jmsConnectionFactory'; @ConditionalOnMissingBean (names: jmsListenerContainerFactory; SearchStrategy: all) did not find any beans (OnBeanCondition) JmsAnnotationDrivenConfiguration#jmsListenerContainerFactoryConfigurer matched: - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; SearchStrategy: all) did not find any beans (OnBeanCondition) JmsAutoConfiguration matched: - @ConditionalOnClass found required classes 'jakarta.jms.Message', 'org.springframework.jms.core.JmsTemplate' (OnClassCondition) - @ConditionalOnBean (types: jakarta.jms.ConnectionFactory; SearchStrategy: all) found bean 'jmsConnectionFactory' (OnBeanCondition) JmsAutoConfiguration.JmsTemplateConfiguration#jmsTemplate matched: - @ConditionalOnSingleCandidate (types: jakarta.jms.ConnectionFactory; SearchStrategy: all) found a single bean 'jmsConnectionFactory'; @ConditionalOnMissingBean (types: org.springframework.jms.core.JmsOperations; SearchStrategy: all) did not find any beans (OnBeanCondition) JmsAutoConfiguration.MessagingTemplateConfiguration matched: - @ConditionalOnClass found required class 'org.springframework.jms.core.JmsMessagingTemplate' (OnClassCondition) JmsAutoConfiguration.MessagingTemplateConfiguration#jmsMessagingTemplate matched: - @ConditionalOnSingleCandidate (types: org.springframework.jms.core.JmsTemplate; SearchStrategy: all) found a single bean 'jmsTemplate'; @ConditionalOnMissingBean (types: org.springframework.jms.core.JmsMessageOperations; SearchStrategy: all) did not find any beans (OnBeanCondition)
Interface | Function |
---|---|
org.springframework.jms.support.destination.DestinationResolver | lookup jakarta.jms.Destination instance by String name |
org.springframework.transaction.jta.JtaTransactionManager | control transaction by JTA |
org.springframework.jms.support.converter.MessageConverter | serialize/deserialize DTO instance |
jakarta.jms.ExceptionListener | processor when jakarta.jms.JMSException throws. One implementation is SingleConnectionFactory, connection managed by that class will be restarted once exception is catched |
io.micrometer.observation.ObservationRegistry | for statistics |
ActiveMQ的实现是org.apache.activemq.ActiveMQConnectionFactory,但Spring Framework并不直接使用它。该类由 org.springframework.jms.connection.CachingConnectionFactory 包装用于以下
通过org.springframework.jms.core.JmsTemplate
发送消息
<dependency> <groupId>org.springframework.boot</groupId> <!--<artifactId>spring-boot-starter-artemis</artifactId>--> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <!--<artifactId>artemis-jakarta-server</artifactId>--> <artifactId>activemq-broker</artifactId> <scope>runtime</scope> </dependency> <!-- ... -->
JmsTemplate bean 是由 org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration.JmsTemplateConfiguration#jmsTemplate 构建的。反序列化 DTO 需要 MessageConverter bean。
DestinationResolver 使用的是 org.springframework.jms.support.destination.DynamicDestinationResolver,该类只是通过调用 jakarta.jms.Destination 实例来获取 jakarta.jms.Destination 实例🎜>jakarta.jms.Session#createTopic 或 jakarta.jms.Session#createQueue
.attribute | Function |
---|---|
id | prefix of thread name which run listener |
containerFactory | bean name of JmsListenerContainerFactory instance |
destination | the destination name for this listener |
subscription | the name of the durable subscription, if any |
selector | an optional message selector for this listener |
concurrency | number of thread running listener |
在 JMS 规范中,支持异步消息处理,并且侦听器在 JMS 提供者的线程下运行。
<dependency> <groupId>org.springframework.boot</groupId> <!--<artifactId>spring-boot-starter-artemis</artifactId>--> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <!--<artifactId>artemis-jakarta-server</artifactId>--> <artifactId>activemq-broker</artifactId> <scope>runtime</scope> </dependency> <!-- ... -->
但是 Spring Framework 中不使用异步方法,而是使用同步 API(轮询)。实际代码位于 org.springframework.jms.support.destination.JmsDestinationAccessor#receiveFromConsumer.
#spring.artemis.mode=embedded debug=true spring.activemq.broker-url=vm://localhost?broker.persistent=false
org.springframework.jms.listener.DefaultMessageListenerContainer.AsyncMessageListenerInvoker 类用于执行定期轮询作业。这是安排在 org.springframework.core.task.SimpleAsyncTaskExecutor.
为一个 @JmsListener 带注释的函数创建一个 DefaultMessageListenerContainer 实例。这是由 org.springframework.jms.config.DefaultJmsListenerContainerFactory.
生成的当然MessageConverter和ExceptionListener实例是必要的。
以上是快速了解 Spring Boot 如何支持 JMS的详细内容。更多信息请关注PHP中文网其他相关文章!