Skip to content

Commit eecec41

Browse files
authored
Merge pull request #3005 from ferblaca/GH-3004
Change the use of synchronized in the getBinder method of DefaultBinderFactory class for virtual-threads compliant
2 parents 56047dd + 2f82f3c commit eecec41

File tree

1 file changed

+32
-24
lines changed

1 file changed

+32
-24
lines changed

core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.Map.Entry;
3131
import java.util.Properties;
3232
import java.util.Set;
33+
import java.util.concurrent.locks.ReentrantLock;
3334
import java.util.stream.Stream;
3435

3536
import org.apache.commons.logging.Log;
@@ -98,6 +99,8 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl
9899

99100
private volatile String defaultBinder;
100101

102+
private static final ReentrantLock lock = new ReentrantLock();
103+
101104
public DefaultBinderFactory(Map<String, BinderConfiguration> binderConfigurations,
102105
BinderTypeRegistry binderTypeRegistry, BinderCustomizer binderCustomizer) {
103106
this.binderConfigurations = new HashMap<>(binderConfigurations);
@@ -142,34 +145,39 @@ public void destroy() {
142145

143146
@SuppressWarnings({ "unchecked", "rawtypes" })
144147
@Override
148+
public <T> Binder<T, ?, ?> getBinder(String name, Class<? extends T> bindingTargetType) {
149+
lock.lock();
150+
try {
151+
String binderName = StringUtils.hasText(name) ? name : this.defaultBinder;
145152

146-
public synchronized <T> Binder<T, ?, ?> getBinder(String name, Class<? extends T> bindingTargetType) {
147-
String binderName = StringUtils.hasText(name) ? name : this.defaultBinder;
148-
149-
Map<String, Binder> binders = this.context == null ? Collections.emptyMap() : this.context.getBeansOfType(Binder.class);
150-
Binder<T, ConsumerProperties, ProducerProperties> binder;
151-
if (StringUtils.hasText(binderName) && binders.containsKey(binderName)) {
152-
binder = (Binder<T, ConsumerProperties, ProducerProperties>) this.context.getBean(binderName);
153-
}
154-
else if (binders.size() == 1) {
155-
binder = binders.values().iterator().next();
156-
}
157-
else if (binders.size() > 1) {
158-
throw new IllegalStateException(
153+
Map<String, Binder> binders = this.context == null ? Collections.emptyMap() : this.context.getBeansOfType(Binder.class);
154+
Binder<T, ConsumerProperties, ProducerProperties> binder;
155+
if (StringUtils.hasText(binderName) && binders.containsKey(binderName)) {
156+
binder = (Binder<T, ConsumerProperties, ProducerProperties>) this.context.getBean(binderName);
157+
}
158+
else if (binders.size() == 1) {
159+
binder = binders.values().iterator().next();
160+
}
161+
else if (binders.size() > 1) {
162+
throw new IllegalStateException(
159163
"Multiple binders are available, however neither default nor "
160-
+ "per-destination binder name is provided. Available binders are "
161-
+ binders.keySet());
162-
}
163-
else {
164-
/*
165-
* This is the fallback to the old bootstrap that relies on spring.binders.
166-
*/
167-
binder = this.doGetBinder(binderName, bindingTargetType);
164+
+ "per-destination binder name is provided. Available binders are "
165+
+ binders.keySet());
166+
}
167+
else {
168+
/*
169+
* This is the fallback to the old bootstrap that relies on spring.binders.
170+
*/
171+
binder = this.doGetBinder(binderName, bindingTargetType);
172+
}
173+
if (this.binderCustomizer != null) {
174+
this.binderCustomizer.customize(binder, binderName);
175+
}
176+
return binder;
168177
}
169-
if (this.binderCustomizer != null) {
170-
this.binderCustomizer.customize(binder, binderName);
178+
finally {
179+
lock.unlock();
171180
}
172-
return binder;
173181
}
174182

175183
private <T> Binder<T, ConsumerProperties, ProducerProperties> doGetBinder(String name, Class<? extends T> bindingTargetType) {

0 commit comments

Comments
 (0)