消息
Spring Boot 提供了多个 starter 以支持消息功能。 本节解答在 Spring Boot 中使用消息时常见的问题。
禁用 JMS 事务会话
如果你的 JMS broker 不支持事务会话,则必须完全禁用事务支持。
如果你自定义了 JmsListenerContainerFactory
,则无需额外操作,因为默认情况下它不支持事务。
如果你希望复用 Spring Boot 默认的 DefaultJmsListenerContainerFactoryConfigurer
,可以按如下方式禁用事务会话:
-
Java
-
Kotlin
import jakarta.jms.ConnectionFactory;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.boot.jms.ConnectionFactoryUnwrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
@Configuration(proxyBeanMethods = false)
public class MyJmsConfiguration {
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory listenerFactory = new DefaultJmsListenerContainerFactory();
configurer.configure(listenerFactory, ConnectionFactoryUnwrapper.unwrapCaching(connectionFactory));
listenerFactory.setTransactionManager(null);
listenerFactory.setSessionTransacted(false);
return listenerFactory;
}
}
import jakarta.jms.ConnectionFactory
import org.springframework.boot.jms.ConnectionFactoryUnwrapper
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.jms.config.DefaultJmsListenerContainerFactory
@Configuration(proxyBeanMethods = false)
class MyJmsConfiguration {
@Bean
fun jmsListenerContainerFactory(connectionFactory: ConnectionFactory?,
configurer: DefaultJmsListenerContainerFactoryConfigurer): DefaultJmsListenerContainerFactory {
val listenerFactory = DefaultJmsListenerContainerFactory()
configurer.configure(listenerFactory, ConnectionFactoryUnwrapper.unwrapCaching(connectionFactory))
listenerFactory.setTransactionManager(null)
listenerFactory.setSessionTransacted(false)
return listenerFactory
}
}
上述示例覆盖了默认工厂,若你的应用定义了其他工厂,也应采用相同方式。