Skip to content

Commit f1bc778

Browse files
mp911deodrotbohm
authored andcommitted
DATACMNS-1556 - Remove capturing lambdas from hot code paths.
Replaced orElseThrow with if blocks. Introduce nullable RepositoryComposition.getMethod(Method) to avoid Optional handling in hot code paths.
1 parent 972449e commit f1bc778

File tree

3 files changed

+42
-19
lines changed

3 files changed

+42
-19
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ private boolean isQueryAnnotationPresentOn(Method method) {
180180
*/
181181
@Override
182182
public boolean isCustomMethod(Method method) {
183-
return composition.findMethod(method).isPresent();
183+
return composition.getMethod(method) != null;
184184
}
185185

186186
/*
@@ -200,7 +200,7 @@ public boolean isQueryMethod(Method method) {
200200
public boolean isBaseClassMethod(Method method) {
201201

202202
Assert.notNull(method, "Method must not be null!");
203-
return baseComposition.findMethod(method).isPresent();
203+
return baseComposition.getMethod(method) != null;
204204
}
205205

206206
/*

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

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springframework.data.repository.core.support.MethodLookup.InvokedMethod;
3838
import org.springframework.data.repository.core.support.MethodLookup.MethodPredicate;
3939
import org.springframework.data.util.Streamable;
40+
import org.springframework.lang.Nullable;
4041
import org.springframework.util.Assert;
4142
import org.springframework.util.ClassUtils;
4243
import org.springframework.util.ConcurrentReferenceHashMap;
@@ -70,7 +71,7 @@ public class RepositoryComposition {
7071
private static final RepositoryComposition EMPTY = new RepositoryComposition(RepositoryFragments.empty(),
7172
MethodLookups.direct(), PASSTHRU_ARG_CONVERTER);
7273

73-
private final Map<Method, Optional<Method>> methodCache = new ConcurrentReferenceHashMap<>();
74+
private final Map<Method, Method> methodCache = new ConcurrentReferenceHashMap<>();
7475
private final @Getter RepositoryFragments fragments;
7576
private final @Getter MethodLookup methodLookup;
7677
private final @Getter BiFunction<Method, Object[], Object[]> argumentConverter;
@@ -192,8 +193,11 @@ public boolean isEmpty() {
192193
*/
193194
public Object invoke(Method method, Object... args) throws Throwable {
194195

195-
Method methodToCall = findMethod(method) //
196-
.orElseThrow(() -> new IllegalArgumentException(String.format("No fragment found for method %s", method)));
196+
Method methodToCall = getMethod(method);
197+
198+
if (methodToCall == null) {
199+
throw new IllegalArgumentException(String.format("No fragment found for method %s", method));
200+
}
197201

198202
ReflectionUtils.makeAccessible(methodToCall);
199203

@@ -207,6 +211,18 @@ public Object invoke(Method method, Object... args) throws Throwable {
207211
* @return
208212
*/
209213
public Optional<Method> findMethod(Method method) {
214+
return Optional.ofNullable(getMethod(method));
215+
}
216+
217+
/**
218+
* Find the implementation method for the given {@link Method} invoked on the composite interface.
219+
*
220+
* @param method must not be {@literal null}.
221+
* @return
222+
* @since 2.2
223+
*/
224+
@Nullable
225+
Method getMethod(Method method) {
210226

211227
return methodCache.computeIfAbsent(method,
212228
key -> RepositoryFragments.findMethod(InvokedMethod.of(key), methodLookup, fragments::methods));
@@ -345,21 +361,26 @@ public Stream<Method> methods() {
345361
*/
346362
public Object invoke(Method method, Object[] args) throws Throwable {
347363

348-
RepositoryFragment<?> fragment = fragmentCache.computeIfAbsent(method, key -> {
364+
RepositoryFragment<?> fragment = fragmentCache.computeIfAbsent(method, this::findImplementationFragment);
365+
Optional<?> optional = fragment.getImplementation();
349366

350-
return stream().filter(it -> it.hasMethod(key)) //
351-
.filter(it -> it.getImplementation().isPresent()) //
352-
.findFirst()
353-
.orElseThrow(() -> new IllegalArgumentException(String.format("No fragment found for method %s", key)));
354-
});
367+
if (!optional.isPresent()) {
368+
throw new IllegalArgumentException(String.format("No implementation found for method %s", method));
369+
}
370+
371+
return method.invoke(optional.get(), args);
372+
}
355373

356-
Object target = fragment.getImplementation().orElseThrow(
357-
() -> new IllegalArgumentException(String.format("No implementation found for method %s", method)));
374+
private RepositoryFragment<?> findImplementationFragment(Method key) {
358375

359-
return method.invoke(target, args);
376+
return stream().filter(it -> it.hasMethod(key)) //
377+
.filter(it -> it.getImplementation().isPresent()) //
378+
.findFirst()
379+
.orElseThrow(() -> new IllegalArgumentException(String.format("No fragment found for method %s", key)));
360380
}
361381

362-
private static Optional<Method> findMethod(InvokedMethod invokedMethod, MethodLookup lookup,
382+
@Nullable
383+
private static Method findMethod(InvokedMethod invokedMethod, MethodLookup lookup,
363384
Supplier<Stream<Method>> methodStreamSupplier) {
364385

365386
for (MethodPredicate methodPredicate : lookup.getLookups()) {
@@ -369,11 +390,11 @@ private static Optional<Method> findMethod(InvokedMethod invokedMethod, MethodLo
369390
.findFirst();
370391

371392
if (resolvedMethod.isPresent()) {
372-
return resolvedMethod;
393+
return resolvedMethod.get();
373394
}
374395
}
375396

376-
return Optional.empty();
397+
return null;
377398
}
378399

379400
/*

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,11 @@ static class ImplementedRepositoryFragment<T> implements RepositoryFragment<T> {
160160

161161
private final Optional<Class<T>> interfaceClass;
162162
private final T implementation;
163+
private final Optional<T> optionalImplementation;
163164

164165
/**
165166
* Creates a new {@link ImplementedRepositoryFragment} for the given interface class and implementation.
166-
*
167+
*
167168
* @param interfaceClass must not be {@literal null}.
168169
* @param implementation must not be {@literal null}.
169170
*/
@@ -181,6 +182,7 @@ public ImplementedRepositoryFragment(Optional<Class<T>> interfaceClass, T implem
181182

182183
this.interfaceClass = interfaceClass;
183184
this.implementation = implementation;
185+
this.optionalImplementation = Optional.of(implementation);
184186
}
185187

186188
/*
@@ -198,7 +200,7 @@ public Class<?> getSignatureContributor() {
198200
*/
199201
@Override
200202
public Optional<T> getImplementation() {
201-
return Optional.of(implementation);
203+
return optionalImplementation;
202204
}
203205

204206
/*

0 commit comments

Comments
 (0)