Skip to content

Commit 8fec430

Browse files
committed
Merge pull request #37473 from vpavic
* gh-37473: Polish "Add config prop for JMS listener's sessionTransacted flag" Add config prop for JMS listener's sessionTransacted flag Closes gh-37473
2 parents b7facec + 0d2eaa7 commit 8fec430

File tree

3 files changed

+52
-5
lines changed

3 files changed

+52
-5
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/DefaultJmsListenerContainerFactoryConfigurer.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
2121
import jakarta.jms.ConnectionFactory;
2222
import jakarta.jms.ExceptionListener;
2323

24+
import org.springframework.boot.autoconfigure.jms.JmsProperties.Listener.Session;
2425
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
2526
import org.springframework.jms.support.converter.MessageConverter;
2627
import org.springframework.jms.support.destination.DestinationResolver;
@@ -32,6 +33,7 @@
3233
*
3334
* @author Stephane Nicoll
3435
* @author Eddú Meléndez
36+
* @author Vedran Pavic
3537
* @since 1.3.3
3638
*/
3739
public final class DefaultJmsListenerContainerFactoryConfigurer {
@@ -101,12 +103,18 @@ public void configure(DefaultJmsListenerContainerFactory factory, ConnectionFact
101103
Assert.notNull(connectionFactory, "ConnectionFactory must not be null");
102104
factory.setConnectionFactory(connectionFactory);
103105
factory.setPubSubDomain(this.jmsProperties.isPubSubDomain());
106+
JmsProperties.Listener listener = this.jmsProperties.getListener();
107+
Session session = listener.getSession();
108+
Boolean sessionTransacted = session.getTransacted();
104109
if (this.transactionManager != null) {
105110
factory.setTransactionManager(this.transactionManager);
106111
}
107-
else {
112+
else if (sessionTransacted == null) {
108113
factory.setSessionTransacted(true);
109114
}
115+
if (sessionTransacted != null) {
116+
factory.setSessionTransacted(sessionTransacted);
117+
}
110118
if (this.destinationResolver != null) {
111119
factory.setDestinationResolver(this.destinationResolver);
112120
}
@@ -116,9 +124,8 @@ public void configure(DefaultJmsListenerContainerFactory factory, ConnectionFact
116124
if (this.exceptionListener != null) {
117125
factory.setExceptionListener(this.exceptionListener);
118126
}
119-
JmsProperties.Listener listener = this.jmsProperties.getListener();
120127
factory.setAutoStartup(listener.isAutoStartup());
121-
factory.setSessionAcknowledgeMode(listener.getSession().getAcknowledgeMode().getMode());
128+
factory.setSessionAcknowledgeMode(session.getAcknowledgeMode().getMode());
122129
String concurrency = listener.formatConcurrency();
123130
if (concurrency != null) {
124131
factory.setConcurrency(concurrency);

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsProperties.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,12 @@ public static class Session {
234234
*/
235235
private AcknowledgeMode acknowledgeMode = AcknowledgeMode.AUTO;
236236

237+
/**
238+
* Whether the listener container should use transacted JMS sessions. Defaults
239+
* to false in the presence of a JtaTransactionManager and true otherwise.
240+
*/
241+
private Boolean transacted;
242+
237243
public AcknowledgeMode getAcknowledgeMode() {
238244
return this.acknowledgeMode;
239245
}
@@ -242,6 +248,14 @@ public void setAcknowledgeMode(AcknowledgeMode acknowledgeMode) {
242248
this.acknowledgeMode = acknowledgeMode;
243249
}
244250

251+
public Boolean getTransacted() {
252+
return this.transacted;
253+
}
254+
255+
public void setTransacted(Boolean transacted) {
256+
this.transacted = transacted;
257+
}
258+
245259
}
246260

247261
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
* @author Stephane Nicoll
5858
* @author Aurélien Leboulanger
5959
* @author Eddú Meléndez
60+
* @author Vedran Pavic
6061
*/
6162
class JmsAutoConfigurationTests {
6263

@@ -143,7 +144,8 @@ void jmsListenerContainerFactoryWhenMultipleConnectionFactoryBeansShouldBackOff(
143144
void testJmsListenerContainerFactoryWithCustomSettings() {
144145
this.contextRunner.withUserConfiguration(EnableJmsConfiguration.class)
145146
.withPropertyValues("spring.jms.listener.autoStartup=false",
146-
"spring.jms.listener.session.acknowledgeMode=client", "spring.jms.listener.minConcurrency=2",
147+
"spring.jms.listener.session.acknowledgeMode=client",
148+
"spring.jms.listener.session.transacted=false", "spring.jms.listener.minConcurrency=2",
147149
"spring.jms.listener.receiveTimeout=2s", "spring.jms.listener.maxConcurrency=10")
148150
.run(this::testJmsListenerContainerFactoryWithCustomSettings);
149151
}
@@ -152,6 +154,7 @@ private void testJmsListenerContainerFactoryWithCustomSettings(AssertableApplica
152154
DefaultMessageListenerContainer container = getContainer(loaded, "jmsListenerContainerFactory");
153155
assertThat(container.isAutoStartup()).isFalse();
154156
assertThat(container.getSessionAcknowledgeMode()).isEqualTo(Session.CLIENT_ACKNOWLEDGE);
157+
assertThat(container.isSessionTransacted()).isFalse();
155158
assertThat(container.getConcurrentConsumers()).isEqualTo(2);
156159
assertThat(container.getMaxConcurrentConsumers()).isEqualTo(10);
157160
assertThat(container).hasFieldOrPropertyWithValue("receiveTimeout", 2000L);
@@ -179,6 +182,18 @@ void testDefaultContainerFactoryWithJtaTransactionManager() {
179182
});
180183
}
181184

185+
@Test
186+
void testDefaultContainerFactoryWithJtaTransactionManagerAndSessionTransactedEnabled() {
187+
this.contextRunner.withUserConfiguration(TestConfiguration7.class, EnableJmsConfiguration.class)
188+
.withPropertyValues("spring.jms.listener.session.transacted=true")
189+
.run((context) -> {
190+
DefaultMessageListenerContainer container = getContainer(context, "jmsListenerContainerFactory");
191+
assertThat(container.isSessionTransacted()).isTrue();
192+
assertThat(container).hasFieldOrPropertyWithValue("transactionManager",
193+
context.getBean(JtaTransactionManager.class));
194+
});
195+
}
196+
182197
@Test
183198
void testDefaultContainerFactoryNonJtaTransactionManager() {
184199
this.contextRunner.withUserConfiguration(TestConfiguration8.class, EnableJmsConfiguration.class)
@@ -198,6 +213,17 @@ void testDefaultContainerFactoryNoTransactionManager() {
198213
});
199214
}
200215

216+
@Test
217+
void testDefaultContainerFactoryNoTransactionManagerAndSessionTransactedDisabled() {
218+
this.contextRunner.withUserConfiguration(EnableJmsConfiguration.class)
219+
.withPropertyValues("spring.jms.listener.session.transacted=false")
220+
.run((context) -> {
221+
DefaultMessageListenerContainer container = getContainer(context, "jmsListenerContainerFactory");
222+
assertThat(container.isSessionTransacted()).isFalse();
223+
assertThat(container).hasFieldOrPropertyWithValue("transactionManager", null);
224+
});
225+
}
226+
201227
@Test
202228
void testDefaultContainerFactoryWithMessageConverters() {
203229
this.contextRunner.withUserConfiguration(MessageConvertersConfiguration.class, EnableJmsConfiguration.class)

0 commit comments

Comments
 (0)