Skip to content

Commit 6190baa

Browse files
committed
Move ReactiveWrappers into o.s.d.util package.
ReactiveWrappers is not tied to repositories so it does not need to reside in the repository.util package. This utility is now located in the data.util package for a better module design and to prevent package cycles. See #2708
1 parent 5b784d0 commit 6190baa

File tree

12 files changed

+285
-107
lines changed

12 files changed

+285
-107
lines changed

src/main/java/org/springframework/data/aot/AuditingBeanRegistrationAotProcessor.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.core.DecoratingProxy;
2626
import org.springframework.data.domain.AuditorAware;
2727
import org.springframework.data.domain.ReactiveAuditorAware;
28+
import org.springframework.data.util.ReactiveWrappers;
2829
import org.springframework.lang.Nullable;
2930
import org.springframework.util.ClassUtils;
3031

@@ -38,8 +39,6 @@
3839
*/
3940
class AuditingBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
4041

41-
private static final boolean PROJECT_REACTOR_PRESENT = ClassUtils.isPresent("reactor.core.publisher.Flux",
42-
AuditingBeanRegistrationAotProcessor.class.getClassLoader());
4342

4443
@Nullable
4544
@Override
@@ -50,7 +49,7 @@ public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registe
5049
generationContext.getRuntimeHints());
5150
}
5251

53-
if (PROJECT_REACTOR_PRESENT && isReactiveAuditorAware(registeredBean)) {
52+
if (ReactiveWrappers.PROJECT_REACTOR_PRESENT && isReactiveAuditorAware(registeredBean)) {
5453
return (generationContext, beanRegistrationCode) -> registerSpringProxy(ReactiveAuditorAware.class,
5554
generationContext.getRuntimeHints());
5655
}

src/main/java/org/springframework/data/querydsl/aot/QuerydslHints.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
2525
import org.springframework.data.querydsl.QuerydslUtils;
2626
import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor;
27+
import org.springframework.data.util.ReactiveWrappers;
2728
import org.springframework.lang.Nullable;
28-
import org.springframework.util.ClassUtils;
2929

3030
import com.querydsl.core.types.Predicate;
3131

@@ -50,7 +50,7 @@ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader)
5050
builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS);
5151
});
5252

53-
if (ClassUtils.isPresent("reactor.core.publisher.Flux", classLoader)) {
53+
if (ReactiveWrappers.PROJECT_REACTOR_PRESENT) {
5454

5555
// repository infrastructure
5656
hints.reflection().registerTypes(Arrays.asList( //

src/main/java/org/springframework/data/repository/aot/hint/RepositoryRuntimeHints.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
import org.springframework.data.repository.query.FluentQuery.ReactiveFluentQuery;
3737
import org.springframework.data.repository.query.QueryByExampleExecutor;
3838
import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor;
39+
import org.springframework.data.util.ReactiveWrappers;
3940
import org.springframework.lang.Nullable;
40-
import org.springframework.util.ClassUtils;
4141

4242
/**
4343
* {@link RuntimeHintsRegistrar} holding required hints to bootstrap data repositories. <br />
@@ -49,9 +49,6 @@
4949
*/
5050
class RepositoryRuntimeHints implements RuntimeHintsRegistrar {
5151

52-
private static final boolean PROJECT_REACTOR_PRESENT = ClassUtils.isPresent("reactor.core.publisher.Flux",
53-
RepositoryRuntimeHints.class.getClassLoader());
54-
5552
@Override
5653
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
5754

@@ -71,7 +68,7 @@ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader)
7168
builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS);
7269
});
7370

74-
if (PROJECT_REACTOR_PRESENT) {
71+
if (ReactiveWrappers.PROJECT_REACTOR_PRESENT) {
7572

7673
// repository infrastructure
7774
hints.reflection().registerTypes(Arrays.asList( //

src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
import org.springframework.data.repository.core.RepositoryMetadata;
2929
import org.springframework.data.repository.util.QueryExecutionConverters;
3030
import org.springframework.data.repository.util.ReactiveWrapperConverters;
31-
import org.springframework.data.repository.util.ReactiveWrappers;
3231
import org.springframework.data.util.KotlinReflectionUtils;
3332
import org.springframework.data.util.Lazy;
33+
import org.springframework.data.util.ReactiveWrappers;
3434
import org.springframework.data.util.TypeInformation;
3535
import org.springframework.util.Assert;
3636

src/main/java/org/springframework/data/repository/core/support/MethodLookups.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import org.springframework.data.repository.core.support.MethodLookup.MethodPredicate;
3737
import org.springframework.data.repository.util.QueryExecutionConverters;
3838
import org.springframework.data.repository.util.ReactiveWrapperConverters;
39-
import org.springframework.data.repository.util.ReactiveWrappers;
39+
import org.springframework.data.util.ReactiveWrappers;
4040
import org.springframework.lang.Nullable;
4141
import org.springframework.util.Assert;
4242
import org.springframework.util.ObjectUtils;

src/main/java/org/springframework/data/repository/core/support/ReactiveRepositoryFactorySupport.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@
1919
import java.util.Arrays;
2020

2121
import org.reactivestreams.Publisher;
22-
2322
import org.springframework.dao.InvalidDataAccessApiUsageException;
2423
import org.springframework.data.repository.core.RepositoryMetadata;
2524
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
2625
import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider;
2726
import org.springframework.data.repository.util.ReactiveWrapperConverters;
28-
import org.springframework.data.repository.util.ReactiveWrappers;
27+
import org.springframework.data.util.ReactiveWrappers;
2928
import org.springframework.util.ClassUtils;
3029

3130
/**

src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import org.springframework.data.repository.core.support.MethodLookup.InvokedMethod;
3434
import org.springframework.data.repository.core.support.RepositoryInvocationMulticaster.NoOpRepositoryInvocationMulticaster;
3535
import org.springframework.data.repository.util.ReactiveWrapperConverters;
36-
import org.springframework.data.repository.util.ReactiveWrappers;
36+
import org.springframework.data.util.ReactiveWrappers;
3737
import org.springframework.data.util.Streamable;
3838
import org.springframework.lang.Nullable;
3939
import org.springframework.util.Assert;

src/main/java/org/springframework/data/repository/core/support/RepositoryMethodInvoker.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,14 @@
2727
import java.util.stream.Stream;
2828

2929
import org.reactivestreams.Publisher;
30-
3130
import org.springframework.core.KotlinDetector;
3231
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocation;
3332
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocationResult;
3433
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocationResult.State;
3534
import org.springframework.data.repository.query.RepositoryQuery;
3635
import org.springframework.data.repository.util.ReactiveWrapperConverters;
37-
import org.springframework.data.repository.util.ReactiveWrappers;
3836
import org.springframework.data.util.KotlinReflectionUtils;
37+
import org.springframework.data.util.ReactiveWrappers;
3938
import org.springframework.lang.Nullable;
4039

4140
/**

src/main/java/org/springframework/data/repository/util/ReactiveWrapperConverters.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import java.util.function.Function;
2828

2929
import org.reactivestreams.Publisher;
30-
3130
import org.springframework.core.ReactiveAdapter;
3231
import org.springframework.core.ReactiveAdapterRegistry;
3332
import org.springframework.core.convert.ConversionService;
@@ -37,7 +36,7 @@
3736
import org.springframework.core.convert.converter.ConverterFactory;
3837
import org.springframework.core.convert.support.ConfigurableConversionService;
3938
import org.springframework.core.convert.support.GenericConversionService;
40-
import org.springframework.data.repository.util.ReactiveWrappers.ReactiveLibrary;
39+
import org.springframework.data.util.ReactiveWrappers.ReactiveLibrary;
4140
import org.springframework.data.util.TypeInformation;
4241
import org.springframework.lang.NonNull;
4342
import org.springframework.lang.Nullable;
@@ -56,19 +55,22 @@
5655
* @author Christoph Strobl
5756
* @author Hantsy Bai
5857
* @since 2.0
59-
* @see ReactiveWrappers
58+
* @see org.springframework.data.util.ReactiveWrappers
6059
* @see ReactiveAdapterRegistry
6160
*/
6261
public abstract class ReactiveWrapperConverters {
6362

6463
private static final List<ReactiveTypeWrapper<?>> REACTIVE_WRAPPERS = new ArrayList<>();
6564
private static final GenericConversionService GENERIC_CONVERSION_SERVICE = new GenericConversionService();
6665

67-
private static final boolean RXJAVA3_PRESENT = ReactiveWrappers.isAvailable(ReactiveLibrary.RXJAVA3);
68-
private static final boolean REACTOR_PRESENT = ReactiveWrappers.isAvailable(ReactiveLibrary.PROJECT_REACTOR);
69-
private static final boolean KOTLIN_COROUTNES_PRESENT = ReactiveWrappers
66+
private static final boolean RXJAVA3_PRESENT = org.springframework.data.util.ReactiveWrappers
67+
.isAvailable(ReactiveLibrary.RXJAVA3);
68+
private static final boolean REACTOR_PRESENT = org.springframework.data.util.ReactiveWrappers
69+
.isAvailable(ReactiveLibrary.PROJECT_REACTOR);
70+
private static final boolean KOTLIN_COROUTNES_PRESENT = org.springframework.data.util.ReactiveWrappers
7071
.isAvailable(ReactiveLibrary.KOTLIN_COROUTINES);
71-
private static final boolean MUTINY_PRESENT = ReactiveWrappers.isAvailable(ReactiveLibrary.MUTINY);
72+
private static final boolean MUTINY_PRESENT = org.springframework.data.util.ReactiveWrappers
73+
.isAvailable(ReactiveLibrary.MUTINY);
7274

7375
static {
7476

@@ -548,8 +550,8 @@ static class RegistryHolder {
548550

549551
static {
550552

551-
if (ReactiveWrappers.isAvailable(ReactiveLibrary.PROJECT_REACTOR)) {
552-
REACTIVE_ADAPTER_REGISTRY = new ReactiveAdapterRegistry();
553+
if (org.springframework.data.util.ReactiveWrappers.PROJECT_REACTOR_PRESENT) {
554+
REACTIVE_ADAPTER_REGISTRY = ReactiveAdapterRegistry.getSharedInstance();
553555
} else {
554556
REACTIVE_ADAPTER_REGISTRY = null;
555557
}

src/main/java/org/springframework/data/repository/util/ReactiveWrappers.java

Lines changed: 16 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,7 @@
1818
import reactor.core.publisher.Flux;
1919
import reactor.core.publisher.Mono;
2020

21-
import java.util.Arrays;
22-
import java.util.Map;
23-
import java.util.Optional;
24-
25-
import org.springframework.core.ReactiveAdapter;
26-
import org.springframework.core.ReactiveAdapterRegistry;
27-
import org.springframework.core.ReactiveTypeDescriptor;
28-
import org.springframework.data.util.ProxyUtils;
29-
import org.springframework.data.util.ReflectionUtils;
3021
import org.springframework.util.Assert;
31-
import org.springframework.util.ClassUtils;
32-
import org.springframework.util.ConcurrentReferenceHashMap;
3322

3423
/**
3524
* Utility class to expose details about reactive wrapper types. This class exposes whether a reactive wrapper is
@@ -54,33 +43,21 @@
5443
* @see io.smallrye.mutiny.Uni
5544
* @see Mono
5645
* @see Flux
46+
* @deprecated since 3.0, use {@link org.springframework.data.util.ReactiveWrappers} instead as the utility was moved
47+
* into the {@code org.springframework.data.util} package.
5748
*/
49+
@Deprecated(since = "3.0", forRemoval = true)
5850
public abstract class ReactiveWrappers {
5951

60-
private static final boolean PROJECT_REACTOR_PRESENT = ClassUtils.isPresent("reactor.core.publisher.Flux",
61-
ReactiveWrappers.class.getClassLoader());
62-
63-
private static final boolean RXJAVA3_PRESENT = ClassUtils.isPresent("io.reactivex.rxjava3.core.Flowable",
64-
ReactiveWrappers.class.getClassLoader());
65-
66-
private static final boolean KOTLIN_COROUTINES_PRESENT = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt",
67-
ReactiveWrappers.class.getClassLoader());
68-
69-
private static final boolean MUTINY_PRESENT = ClassUtils.isPresent("io.smallrye.mutiny.Multi",
70-
ReactiveWrappers.class.getClassLoader());
71-
72-
private static final Map<Class<?>, Boolean> IS_REACTIVE_TYPE = new ConcurrentReferenceHashMap<>();
73-
74-
private static final boolean IS_REACTIVE_AVAILABLE = Arrays.stream(ReactiveLibrary.values())
75-
.anyMatch(ReactiveWrappers::isAvailable);
76-
7752
private ReactiveWrappers() {}
7853

7954
/**
8055
* Enumeration of supported reactive libraries.
8156
*
8257
* @author Mark Paluch
58+
* @deprecated use {@link org.springframework.data.util.ReactiveWrappers.ReactiveLibrary} instead.
8359
*/
60+
@Deprecated(since = "3.0", forRemoval = true)
8461
public enum ReactiveLibrary {
8562

8663
PROJECT_REACTOR, RXJAVA3, KOTLIN_COROUTINES, MUTINY;
@@ -93,7 +70,7 @@ public enum ReactiveLibrary {
9370
* @return {@literal true} if reactive support is available.
9471
*/
9572
public static boolean isAvailable() {
96-
return IS_REACTIVE_AVAILABLE;
73+
return org.springframework.data.util.ReactiveWrappers.isAvailable();
9774
}
9875

9976
/**
@@ -108,13 +85,14 @@ public static boolean isAvailable(ReactiveLibrary reactiveLibrary) {
10885

10986
switch (reactiveLibrary) {
11087
case PROJECT_REACTOR:
111-
return PROJECT_REACTOR_PRESENT;
88+
return org.springframework.data.util.ReactiveWrappers.PROJECT_REACTOR_PRESENT;
11289
case RXJAVA3:
113-
return RXJAVA3_PRESENT;
90+
return org.springframework.data.util.ReactiveWrappers.RXJAVA3_PRESENT;
11491
case KOTLIN_COROUTINES:
115-
return PROJECT_REACTOR_PRESENT && KOTLIN_COROUTINES_PRESENT;
92+
return org.springframework.data.util.ReactiveWrappers.PROJECT_REACTOR_PRESENT
93+
&& org.springframework.data.util.ReactiveWrappers.KOTLIN_COROUTINES_PRESENT;
11694
case MUTINY:
117-
return MUTINY_PRESENT;
95+
return org.springframework.data.util.ReactiveWrappers.MUTINY_PRESENT;
11896
default:
11997
throw new IllegalArgumentException(String.format("Reactive library %s not supported", reactiveLibrary));
12098
}
@@ -127,7 +105,7 @@ public static boolean isAvailable(ReactiveLibrary reactiveLibrary) {
127105
* @return {@literal true} if the {@code type} is a supported reactive wrapper type.
128106
*/
129107
public static boolean supports(Class<?> type) {
130-
return isAvailable() && IS_REACTIVE_TYPE.computeIfAbsent(type, key -> isWrapper(ProxyUtils.getUserClass(key)));
108+
return org.springframework.data.util.ReactiveWrappers.supports(type);
131109
}
132110

133111
/**
@@ -140,9 +118,7 @@ public static boolean usesReactiveType(Class<?> type) {
140118

141119
Assert.notNull(type, "Type must not be null");
142120

143-
return Arrays.stream(type.getMethods())//
144-
.flatMap(ReflectionUtils::returnTypeAndParameters)//
145-
.anyMatch(ReactiveWrappers::supports);
121+
return org.springframework.data.util.ReactiveWrappers.usesReactiveType(type);
146122
}
147123

148124
/**
@@ -155,7 +131,7 @@ public static boolean isNoValueType(Class<?> type) {
155131

156132
Assert.notNull(type, "Candidate type must not be null");
157133

158-
return findDescriptor(type).map(ReactiveTypeDescriptor::isNoValue).orElse(false);
134+
return org.springframework.data.util.ReactiveWrappers.isNoValueType(type);
159135
}
160136

161137
/**
@@ -168,7 +144,7 @@ public static boolean isSingleValueType(Class<?> type) {
168144

169145
Assert.notNull(type, "Candidate type must not be null");
170146

171-
return findDescriptor(type).map(it -> !it.isMultiValue() && !it.isNoValue()).orElse(false);
147+
return org.springframework.data.util.ReactiveWrappers.isSingleValueType(type);
172148
}
173149

174150
/**
@@ -183,46 +159,7 @@ public static boolean isMultiValueType(Class<?> type) {
183159

184160
Assert.notNull(type, "Candidate type must not be null");
185161

186-
// Prevent single-types with a multi-hierarchy supertype to be reported as multi type
187-
// See Mono implements Publisher
188-
return isSingleValueType(type) ? false
189-
: findDescriptor(type).map(ReactiveTypeDescriptor::isMultiValue).orElse(false);
162+
return org.springframework.data.util.ReactiveWrappers.isMultiValueType(type);
190163
}
191164

192-
/**
193-
* Returns whether the given type is a reactive wrapper type.
194-
*
195-
* @param type must not be {@literal null}.
196-
* @return
197-
*/
198-
private static boolean isWrapper(Class<?> type) {
199-
200-
Assert.notNull(type, "Candidate type must not be null");
201-
202-
return isNoValueType(type) || isSingleValueType(type) || isMultiValueType(type);
203-
}
204-
205-
/**
206-
* Looks up a {@link ReactiveTypeDescriptor} for the given wrapper type.
207-
*
208-
* @param type must not be {@literal null}.
209-
* @return
210-
*/
211-
private static Optional<ReactiveTypeDescriptor> findDescriptor(Class<?> type) {
212-
213-
Assert.notNull(type, "Wrapper type must not be null");
214-
215-
ReactiveAdapterRegistry adapterRegistry = ReactiveWrapperConverters.RegistryHolder.REACTIVE_ADAPTER_REGISTRY;
216-
217-
if (adapterRegistry == null) {
218-
return Optional.empty();
219-
}
220-
221-
ReactiveAdapter adapter = adapterRegistry.getAdapter(type);
222-
if (adapter != null && adapter.getDescriptor().isDeferred()) {
223-
return Optional.of(adapter.getDescriptor());
224-
}
225-
226-
return Optional.empty();
227-
}
228165
}

0 commit comments

Comments
 (0)