37
37
import org .springframework .data .repository .core .support .MethodLookup .InvokedMethod ;
38
38
import org .springframework .data .repository .core .support .MethodLookup .MethodPredicate ;
39
39
import org .springframework .data .util .Streamable ;
40
+ import org .springframework .lang .Nullable ;
40
41
import org .springframework .util .Assert ;
41
42
import org .springframework .util .ClassUtils ;
42
43
import org .springframework .util .ConcurrentReferenceHashMap ;
@@ -70,7 +71,7 @@ public class RepositoryComposition {
70
71
private static final RepositoryComposition EMPTY = new RepositoryComposition (RepositoryFragments .empty (),
71
72
MethodLookups .direct (), PASSTHRU_ARG_CONVERTER );
72
73
73
- private final Map <Method , Optional < Method > > methodCache = new ConcurrentReferenceHashMap <>();
74
+ private final Map <Method , Method > methodCache = new ConcurrentReferenceHashMap <>();
74
75
private final @ Getter RepositoryFragments fragments ;
75
76
private final @ Getter MethodLookup methodLookup ;
76
77
private final @ Getter BiFunction <Method , Object [], Object []> argumentConverter ;
@@ -192,8 +193,11 @@ public boolean isEmpty() {
192
193
*/
193
194
public Object invoke (Method method , Object ... args ) throws Throwable {
194
195
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
+ }
197
201
198
202
ReflectionUtils .makeAccessible (methodToCall );
199
203
@@ -207,6 +211,18 @@ public Object invoke(Method method, Object... args) throws Throwable {
207
211
* @return
208
212
*/
209
213
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 ) {
210
226
211
227
return methodCache .computeIfAbsent (method ,
212
228
key -> RepositoryFragments .findMethod (InvokedMethod .of (key ), methodLookup , fragments ::methods ));
@@ -345,21 +361,26 @@ public Stream<Method> methods() {
345
361
*/
346
362
public Object invoke (Method method , Object [] args ) throws Throwable {
347
363
348
- RepositoryFragment <?> fragment = fragmentCache .computeIfAbsent (method , key -> {
364
+ RepositoryFragment <?> fragment = fragmentCache .computeIfAbsent (method , this ::findImplementationFragment );
365
+ Optional <?> optional = fragment .getImplementation ();
349
366
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
+ }
355
373
356
- Object target = fragment .getImplementation ().orElseThrow (
357
- () -> new IllegalArgumentException (String .format ("No implementation found for method %s" , method )));
374
+ private RepositoryFragment <?> findImplementationFragment (Method key ) {
358
375
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 )));
360
380
}
361
381
362
- private static Optional <Method > findMethod (InvokedMethod invokedMethod , MethodLookup lookup ,
382
+ @ Nullable
383
+ private static Method findMethod (InvokedMethod invokedMethod , MethodLookup lookup ,
363
384
Supplier <Stream <Method >> methodStreamSupplier ) {
364
385
365
386
for (MethodPredicate methodPredicate : lookup .getLookups ()) {
@@ -369,11 +390,11 @@ private static Optional<Method> findMethod(InvokedMethod invokedMethod, MethodLo
369
390
.findFirst ();
370
391
371
392
if (resolvedMethod .isPresent ()) {
372
- return resolvedMethod ;
393
+ return resolvedMethod . get () ;
373
394
}
374
395
}
375
396
376
- return Optional . empty () ;
397
+ return null ;
377
398
}
378
399
379
400
/*
0 commit comments