Skip to content

Commit bc8e525

Browse files
committed
Add shared instance of ReactiveAdapterRegistry
Issue: SPR-16218
1 parent 6f24c0d commit bc8e525

File tree

39 files changed

+74
-42
lines changed

39 files changed

+74
-42
lines changed

spring-core/src/main/java/org/springframework/core/Conventions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public abstract class Conventions {
5959
}
6060

6161
private static final ReactiveAdapterRegistry reactiveAdapterRegistry =
62-
new ReactiveAdapterRegistry();
62+
ReactiveAdapterRegistry.getSharedInstance();
6363

6464

6565
/**

spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@
3333
import org.springframework.util.ClassUtils;
3434
import org.springframework.util.ReflectionUtils;
3535

36-
import static org.springframework.core.ReactiveTypeDescriptor.*;
36+
import static org.springframework.core.ReactiveTypeDescriptor.multiValue;
37+
import static org.springframework.core.ReactiveTypeDescriptor.noValue;
38+
import static org.springframework.core.ReactiveTypeDescriptor.singleOptionalValue;
39+
import static org.springframework.core.ReactiveTypeDescriptor.singleRequiredValue;
3740

3841
/**
3942
* A registry of adapters to adapt a Reactive Streams {@link Publisher} to/from
@@ -50,6 +53,9 @@
5053
*/
5154
public class ReactiveAdapterRegistry {
5255

56+
@Nullable
57+
private static volatile ReactiveAdapterRegistry sharedInstance;
58+
5359
private final boolean reactorPresent;
5460

5561
private final List<ReactiveAdapter> adapters = new ArrayList<>(32);
@@ -98,6 +104,31 @@ public ReactiveAdapterRegistry() {
98104
}
99105

100106

107+
/**
108+
* Return a shared default {@code ReactiveAdapterRegistry} instance, lazily
109+
* building it once needed.
110+
* <p><b>NOTE:</b> We highly recommend passing a long-lived, pre-configured
111+
* {@code ReactiveAdapterRegistry} instance for customization purposes.
112+
* This accessor is only meant as a fallback for code paths that want to
113+
* fall back on a default instance if one isn't provided.
114+
* @return the shared {@code ReactiveAdapterRegistry} instance (never {@code null})
115+
* @since 5.0.2
116+
*/
117+
public static ReactiveAdapterRegistry getSharedInstance() {
118+
ReactiveAdapterRegistry ar = sharedInstance;
119+
if (ar == null) {
120+
synchronized (ReactiveAdapterRegistry.class) {
121+
ar = sharedInstance;
122+
if (ar == null) {
123+
ar = new ReactiveAdapterRegistry();
124+
sharedInstance = ar;
125+
}
126+
}
127+
}
128+
return ar;
129+
}
130+
131+
101132
/**
102133
* Whether the registry has any adapters which would be the case if any of
103134
* Reactor, RxJava 2, or RxJava 1 (+ RxJava Reactive Streams bridge) are

spring-core/src/test/java/org/springframework/core/convert/support/ReactiveAdapterRegistryTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
@SuppressWarnings("unchecked")
5151
public class ReactiveAdapterRegistryTests {
5252

53-
private final ReactiveAdapterRegistry registry = new ReactiveAdapterRegistry();
53+
private final ReactiveAdapterRegistry registry = ReactiveAdapterRegistry.getSharedInstance();
5454

5555

5656
@Test

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
6666

6767
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
6868

69-
private ReactiveAdapterRegistry reactiveAdapterRegistry = new ReactiveAdapterRegistry();
69+
private ReactiveAdapterRegistry reactiveAdapterRegistry = ReactiveAdapterRegistry.getSharedInstance();
7070

7171

7272
public InvocableHandlerMethod(HandlerMethod handlerMethod) {

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public abstract class AbstractMessageReaderArgumentResolver extends HandlerMetho
8181
* @param readers readers to convert from the request body
8282
*/
8383
protected AbstractMessageReaderArgumentResolver(List<HttpMessageReader<?>> readers) {
84-
this(readers, new ReactiveAdapterRegistry());
84+
this(readers, ReactiveAdapterRegistry.getSharedInstance());
8585
}
8686

8787
/**

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa
6060
protected AbstractMessageWriterResultHandler(List<HttpMessageWriter<?>> messageWriters,
6161
RequestedContentTypeResolver contentTypeResolver) {
6262

63-
this(messageWriters, contentTypeResolver, new ReactiveAdapterRegistry());
63+
this(messageWriters, contentTypeResolver, ReactiveAdapterRegistry.getSharedInstance());
6464
}
6565

6666
/**

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public void afterPropertiesSet() throws Exception {
163163
this.argumentResolverConfigurer = new ArgumentResolverConfigurer();
164164
}
165165
if (this.reactiveAdapterRegistry == null) {
166-
this.reactiveAdapterRegistry = new ReactiveAdapterRegistry();
166+
this.reactiveAdapterRegistry = ReactiveAdapterRegistry.getSharedInstance();
167167
}
168168

169169
this.methodResolver = new ControllerMethodResolver(this.argumentResolverConfigurer,

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class ResponseBodyResultHandler extends AbstractMessageWriterResultHandle
5656
public ResponseBodyResultHandler(List<HttpMessageWriter<?>> writers,
5757
RequestedContentTypeResolver resolver) {
5858

59-
this(writers, resolver, new ReactiveAdapterRegistry());
59+
this(writers, resolver, ReactiveAdapterRegistry.getSharedInstance());
6060
}
6161

6262
/**

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand
6363
public ResponseEntityResultHandler(List<HttpMessageWriter<?>> writers,
6464
RequestedContentTypeResolver resolver) {
6565

66-
this(writers, resolver, new ReactiveAdapterRegistry());
66+
this(writers, resolver, ReactiveAdapterRegistry.getSharedInstance());
6767
}
6868

6969
/**

spring-webflux/src/main/java/org/springframework/web/reactive/result/view/AbstractView.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public abstract class AbstractView implements View, ApplicationContextAware {
7070

7171

7272
public AbstractView() {
73-
this(new ReactiveAdapterRegistry());
73+
this(ReactiveAdapterRegistry.getSharedInstance());
7474
}
7575

7676
public AbstractView(ReactiveAdapterRegistry registry) {

0 commit comments

Comments
 (0)