Skip to content

Commit 68bfa9a

Browse files
committed
Performance improvements in ReactiveWrappers and ConvertingPropertyAccessor.
We now cache whether types are reactive wrappers and bypass the ConversionService for assignable primitive values. Closes #2546
1 parent 9146357 commit 68bfa9a

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

src/main/java/org/springframework/data/mapping/model/ConvertingPropertyAccessor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2021 the original author or authors.
2+
* Copyright 2014-2022 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 org.springframework.data.mapping.PersistentPropertyPath;
2222
import org.springframework.lang.Nullable;
2323
import org.springframework.util.Assert;
24+
import org.springframework.util.ClassUtils;
2425

2526
/**
2627
* {@link PersistentPropertyAccessor} that potentially converts the value handed to
@@ -103,7 +104,7 @@ private <S> S convertIfNecessary(@Nullable Object source, Class<S> type) {
103104

104105
return (S) (source == null //
105106
? null //
106-
: type.isAssignableFrom(source.getClass()) //
107+
: ClassUtils.resolvePrimitiveIfNecessary(type).isAssignableFrom(source.getClass()) //
107108
? source //
108109
: conversionService.convert(source, type));
109110
}

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2021 the original author or authors.
2+
* Copyright 2016-2022 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.
@@ -19,13 +19,17 @@
1919
import reactor.core.publisher.Mono;
2020

2121
import java.util.Arrays;
22+
import java.util.Collection;
23+
import java.util.Collections;
24+
import java.util.Map;
2225
import java.util.Optional;
2326

2427
import org.springframework.core.ReactiveTypeDescriptor;
2528
import org.springframework.data.util.ProxyUtils;
2629
import org.springframework.data.util.ReflectionUtils;
2730
import org.springframework.util.Assert;
2831
import org.springframework.util.ClassUtils;
32+
import org.springframework.util.ConcurrentReferenceHashMap;
2933

3034
/**
3135
* Utility class to expose details about reactive wrapper types. This class exposes whether a reactive wrapper is
@@ -65,6 +69,11 @@ public abstract class ReactiveWrappers {
6569
private static final boolean MUTINY_PRESENT = ClassUtils.isPresent("io.smallrye.mutiny.Multi",
6670
ReactiveWrappers.class.getClassLoader());
6771

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+
6877
private ReactiveWrappers() {}
6978

7079
/**
@@ -84,7 +93,7 @@ public enum ReactiveLibrary {
8493
* @return {@literal true} if reactive support is available.
8594
*/
8695
public static boolean isAvailable() {
87-
return Arrays.stream(ReactiveLibrary.values()).anyMatch(ReactiveWrappers::isAvailable);
96+
return IS_REACTIVE_AVAILABLE;
8897
}
8998

9099
/**
@@ -118,7 +127,7 @@ public static boolean isAvailable(ReactiveLibrary reactiveLibrary) {
118127
* @return {@literal true} if the {@code type} is a supported reactive wrapper type.
119128
*/
120129
public static boolean supports(Class<?> type) {
121-
return isAvailable() && isWrapper(ProxyUtils.getUserClass(type));
130+
return isAvailable() && IS_REACTIVE_TYPE.computeIfAbsent(type, key -> isWrapper(ProxyUtils.getUserClass(key)));
122131
}
123132

124133
/**

0 commit comments

Comments
 (0)