Skip to content

Commit 6dc3c11

Browse files
committed
Introduce JmsClient with configurable settings per operation
Closes gh-32501 Closes gh-26840
1 parent 842f582 commit 6dc3c11

File tree

12 files changed

+1509
-146
lines changed

12 files changed

+1509
-146
lines changed
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/*
2+
* Copyright 2002-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.jms.core;
18+
19+
import java.util.Map;
20+
import java.util.Optional;
21+
22+
import jakarta.jms.ConnectionFactory;
23+
import jakarta.jms.Destination;
24+
import org.jspecify.annotations.Nullable;
25+
26+
import org.springframework.jms.support.JmsAccessor;
27+
import org.springframework.messaging.Message;
28+
import org.springframework.messaging.MessagingException;
29+
import org.springframework.messaging.converter.MessageConverter;
30+
import org.springframework.util.Assert;
31+
32+
/**
33+
* The default implementation of {@link JmsClient},
34+
* as created by the static factory methods.
35+
*
36+
* @author Juergen Hoeller
37+
* @since 7.0
38+
* @see JmsClient#create(ConnectionFactory)
39+
* @see JmsClient#create(ConnectionFactory, MessageConverter)
40+
* @see JmsClient#create(JmsOperations)
41+
* @see JmsClient#create(JmsOperations, MessageConverter)
42+
*/
43+
class DefaultJmsClient implements JmsClient {
44+
45+
private final JmsOperations jmsTemplate;
46+
47+
private final @Nullable MessageConverter messageConverter;
48+
49+
50+
public DefaultJmsClient(ConnectionFactory connectionFactory, @Nullable MessageConverter messageConverter) {
51+
this.jmsTemplate = new JmsTemplate(connectionFactory);
52+
this.messageConverter = messageConverter;
53+
}
54+
55+
public DefaultJmsClient(JmsOperations jmsTemplate, @Nullable MessageConverter messageConverter) {
56+
Assert.notNull(jmsTemplate, "JmsTemplate must not be null");
57+
this.jmsTemplate = jmsTemplate;
58+
this.messageConverter = messageConverter;
59+
}
60+
61+
62+
public OperationSpec destination(Destination destination) {
63+
return new DefaultOperationSpec(destination);
64+
}
65+
66+
public OperationSpec destination(String destinationName) {
67+
return new DefaultOperationSpec(destinationName);
68+
}
69+
70+
private JmsMessagingTemplate newDelegate() {
71+
JmsMessagingTemplate delegate = new JmsMessagingTemplate(DefaultJmsClient.this.jmsTemplate);
72+
MessageConverter converter = DefaultJmsClient.this.messageConverter;
73+
if (converter != null) {
74+
delegate.setMessageConverter(converter);
75+
}
76+
return delegate;
77+
}
78+
79+
80+
private class DefaultOperationSpec implements OperationSpec {
81+
82+
private final JmsMessagingTemplate delegate;
83+
84+
private @Nullable JmsTemplate customTemplate;
85+
86+
public DefaultOperationSpec(Destination destination) {
87+
this.delegate = newDelegate();
88+
this.delegate.setDefaultDestination(destination);
89+
}
90+
91+
public DefaultOperationSpec(String destinationName) {
92+
this.delegate = newDelegate();
93+
this.delegate.setDefaultDestinationName(destinationName);
94+
}
95+
96+
private JmsTemplate enforceCustomTemplate(boolean qos) {
97+
if (this.customTemplate == null) {
98+
JmsOperations jmsOperations = DefaultJmsClient.this.jmsTemplate;
99+
if (!(jmsOperations instanceof JmsAccessor original)) {
100+
throw new IllegalStateException(
101+
"Needs to be bound to a JmsAccessor for custom settings support: " + jmsOperations);
102+
}
103+
this.customTemplate = new JmsTemplate(original);
104+
this.delegate.setJmsTemplate(this.customTemplate);
105+
}
106+
if (qos) {
107+
this.customTemplate.setExplicitQosEnabled(true);
108+
}
109+
return this.customTemplate;
110+
}
111+
112+
@Override
113+
public OperationSpec withReceiveTimeout(long receiveTimeout) {
114+
enforceCustomTemplate(false).setReceiveTimeout(receiveTimeout);
115+
return this;
116+
}
117+
118+
@Override
119+
public OperationSpec withDeliveryDelay(long deliveryDelay) {
120+
enforceCustomTemplate(false).setDeliveryDelay(deliveryDelay);
121+
return this;
122+
}
123+
124+
@Override
125+
public OperationSpec withDeliveryPersistent(boolean persistent) {
126+
enforceCustomTemplate(true).setDeliveryPersistent(persistent);
127+
return this;
128+
}
129+
130+
@Override
131+
public OperationSpec withPriority(int priority) {
132+
enforceCustomTemplate(true).setPriority(priority);
133+
return this;
134+
}
135+
136+
@Override
137+
public OperationSpec withTimeToLive(long timeToLive) {
138+
enforceCustomTemplate(true).setTimeToLive(timeToLive);
139+
return this;
140+
}
141+
142+
@Override
143+
public void send(Message<?> message) throws MessagingException {
144+
this.delegate.send(message);
145+
}
146+
147+
@Override
148+
public void send(Object payload) throws MessagingException {
149+
this.delegate.convertAndSend(payload);
150+
}
151+
152+
@Override
153+
public void send(Object payload, Map<String, Object> headers) throws MessagingException {
154+
this.delegate.convertAndSend(payload, headers);
155+
}
156+
157+
@Override
158+
public Optional<Message<?>> receive() throws MessagingException {
159+
return Optional.ofNullable(this.delegate.receive());
160+
}
161+
162+
@Override
163+
public <T> Optional<T> receive(Class<T> targetClass) throws MessagingException {
164+
return Optional.ofNullable(this.delegate.receiveAndConvert(targetClass));
165+
}
166+
167+
@Override
168+
public Optional<Message<?>> receive(String messageSelector) throws MessagingException {
169+
return Optional.ofNullable(this.delegate.receiveSelected(messageSelector));
170+
}
171+
172+
@Override
173+
public <T> Optional<T> receive(String messageSelector, Class<T> targetClass) throws MessagingException {
174+
return Optional.ofNullable(this.delegate.receiveSelectedAndConvert(messageSelector, targetClass));
175+
}
176+
177+
@Override
178+
public Optional<Message<?>> sendAndReceive(Message<?> requestMessage) throws MessagingException {
179+
return Optional.ofNullable(this.delegate.sendAndReceive(requestMessage));
180+
}
181+
182+
@Override
183+
public <T> Optional<T> sendAndReceive(Object request, Class<T> targetClass) throws MessagingException {
184+
return Optional.ofNullable(this.delegate.convertSendAndReceive(request, targetClass));
185+
}
186+
187+
@Override
188+
public <T> Optional<T> sendAndReceive(Object request, Map<String, Object> headers, Class<T> targetClass)
189+
throws MessagingException {
190+
191+
return Optional.ofNullable(this.delegate.convertSendAndReceive(request, headers, targetClass));
192+
}
193+
}
194+
195+
}

0 commit comments

Comments
 (0)