diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java index 53be1cf1f..1eac7f24d 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java @@ -139,7 +139,7 @@ public class RepositoryComposition { REACTIVE_ARGS_CONVERTER); } - return new RepositoryComposition(metadata, RepositoryFragments.empty(), MethodLookups.direct(), + return new RepositoryComposition(metadata, RepositoryFragments.empty(), MethodLookups.forRepositoryTypes(metadata), PASSTHRU_ARG_CONVERTER); } @@ -480,11 +480,8 @@ public class RepositoryComposition { /** * Invoke {@link Method} by resolving the fragment that implements a suitable method. * - * @param repositoryInformation - * @param listener * @param invokedMethod invoked method as per invocation on the interface. * @param methodToCall backend method that is backing the call. - * @param args * @return * @throws Throwable */ @@ -496,8 +493,7 @@ public class RepositoryComposition { /** * Invoke {@link Method} by resolving the fragment that implements a suitable method. * - * @param listener - * @param repositoryInformation + * @param repositoryInterface * @param listener * @param invokedMethod invoked method as per invocation on the interface. * @param methodToCall backend method that is backing the call. diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryMethodInvoker.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryMethodInvoker.java index 199cd1938..9253f7a33 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryMethodInvoker.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryMethodInvoker.java @@ -135,7 +135,7 @@ abstract class RepositoryMethodInvoker { Object result = invokable.invoke(args); if (result != null && ReactiveWrappers.supports(result.getClass())) { - return inferReactiveInvocationCallbacks(repositoryInterface, multicaster, args, result); + return new ReactiveInvocationListenerDecorator().decorate(repositoryInterface, multicaster, args, result); } if (result instanceof Stream) { @@ -169,7 +169,7 @@ abstract class RepositoryMethodInvoker { .captureInvocationOn(repositoryInterface); try { - Publisher result = inferReactiveInvocationCallbacks(repositoryInterface, multicaster, args, + Publisher result = new ReactiveInvocationListenerDecorator().decorate(repositoryInterface, multicaster, args, invokable.invoke(args)); if (returnsReactiveType) { @@ -188,42 +188,7 @@ abstract class RepositoryMethodInvoker { captured.getDuration()); } - private Publisher inferReactiveInvocationCallbacks(Class repositoryInterface, - RepositoryInvocationMulticaster multicaster, Object[] args, Object result) { - if (result instanceof Mono) { - return Mono.usingWhen( - Mono.fromSupplier(() -> RepositoryMethodInvocationCaptor.captureInvocationOn(repositoryInterface)), it -> { - it.trackStart(); - return ReactiveWrapperConverters.toWrapper(result, Mono.class); - }, it -> { - multicaster.notifyListeners(method, args, computeInvocationResult(it.success())); - return Mono.empty(); - }, (it, e) -> { - multicaster.notifyListeners(method, args, computeInvocationResult(it.error(e))); - return Mono.empty(); - }, it -> { - multicaster.notifyListeners(method, args, computeInvocationResult(it.canceled())); - return Mono.empty(); - }); - } - - return Flux.usingWhen( - Mono.fromSupplier(() -> RepositoryMethodInvocationCaptor.captureInvocationOn(repositoryInterface)), it -> { - it.trackStart(); - return result instanceof Publisher ? (Publisher) result - : ReactiveWrapperConverters.toWrapper(result, Publisher.class); - }, it -> { - multicaster.notifyListeners(method, args, computeInvocationResult(it.success())); - return Mono.empty(); - }, (it, e) -> { - multicaster.notifyListeners(method, args, computeInvocationResult(it.error(e))); - return Mono.empty(); - }, it -> { - multicaster.notifyListeners(method, args, computeInvocationResult(it.canceled())); - return Mono.empty(); - }); - } interface Invokable { @@ -240,6 +205,49 @@ abstract class RepositoryMethodInvoker { } } + /** + * Delegate to decorate {@link Publisher} invocations with {@link RepositoryInvocationMulticaster} callbacks. + */ + class ReactiveInvocationListenerDecorator { + + Publisher decorate(Class repositoryInterface, RepositoryInvocationMulticaster multicaster, Object[] args, + Object result) { + + if (result instanceof Mono) { + return Mono.usingWhen( + Mono.fromSupplier(() -> RepositoryMethodInvocationCaptor.captureInvocationOn(repositoryInterface)), it -> { + it.trackStart(); + return ReactiveWrapperConverters.toWrapper(result, Mono.class); + }, it -> { + multicaster.notifyListeners(method, args, computeInvocationResult(it.success())); + return Mono.empty(); + }, (it, e) -> { + multicaster.notifyListeners(method, args, computeInvocationResult(it.error(e))); + return Mono.empty(); + }, it -> { + multicaster.notifyListeners(method, args, computeInvocationResult(it.canceled())); + return Mono.empty(); + }); + } + + return Flux.usingWhen( + Mono.fromSupplier(() -> RepositoryMethodInvocationCaptor.captureInvocationOn(repositoryInterface)), it -> { + it.trackStart(); + return result instanceof Publisher ? (Publisher) result + : ReactiveWrapperConverters.toWrapper(result, Publisher.class); + }, it -> { + multicaster.notifyListeners(method, args, computeInvocationResult(it.success())); + return Mono.empty(); + }, (it, e) -> { + multicaster.notifyListeners(method, args, computeInvocationResult(it.error(e))); + return Mono.empty(); + }, it -> { + multicaster.notifyListeners(method, args, computeInvocationResult(it.canceled())); + return Mono.empty(); + }); + } + } + /** * Implementation to invoke fragment methods. */