Add Coroutines support to Spring AOP
This commit adds support for Kotlin Coroutines to Spring AOP by leveraging CoroutinesUtils#invokeSuspendingFunction in AopUtils#invokeJoinpointUsingReflection to convert it to the equivalent Publisher return value, like in other parts of Spring Framework. That allows method interceptors with Reactive support to process related return values. CglibAopProxy#processReturnType and JdkDynamicAopProxy#invoke take care of the conversion from the Publisher return value to Kotlin Coroutines. Reactive transactional and HTTP service interface support have been refined to leverage those new generic capabilities. Closes gh-22462
This commit is contained in:
@@ -26,8 +26,6 @@ import io.vavr.control.Try;
|
||||
import kotlin.coroutines.Continuation;
|
||||
import kotlin.coroutines.CoroutineContext;
|
||||
import kotlinx.coroutines.Job;
|
||||
import kotlinx.coroutines.reactive.ReactiveFlowKt;
|
||||
import kotlinx.coroutines.reactor.MonoKt;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.reactivestreams.Publisher;
|
||||
@@ -370,12 +368,7 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
if (corInv != null) {
|
||||
callback = () -> KotlinDelegate.invokeSuspendingFunction(method, corInv);
|
||||
}
|
||||
Object result = txSupport.invokeWithinTransaction(method, targetClass, callback, txAttr, rtm);
|
||||
if (corInv != null) {
|
||||
return (hasSuspendingFlowReturnType ? KotlinDelegate.asFlow((Publisher<?>) result) :
|
||||
KotlinDelegate.awaitSingleOrNull((Mono<?>) result, corInv.getContinuation()));
|
||||
}
|
||||
return result;
|
||||
return txSupport.invokeWithinTransaction(method, targetClass, callback, txAttr, rtm);
|
||||
}
|
||||
|
||||
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
|
||||
@@ -896,16 +889,6 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
*/
|
||||
private static class KotlinDelegate {
|
||||
|
||||
private static Object asFlow(Publisher<?> publisher) {
|
||||
return ReactiveFlowKt.asFlow(publisher);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
private static Object awaitSingleOrNull(Mono<?> publisher, Object continuation) {
|
||||
return MonoKt.awaitSingleOrNull(publisher, (Continuation<Object>) continuation);
|
||||
}
|
||||
|
||||
public static Publisher<?> invokeSuspendingFunction(Method method, CoroutinesInvocationCallback callback) {
|
||||
CoroutineContext coroutineContext = ((Continuation<?>) callback.getContinuation()).getContext().minusKey(Job.Key);
|
||||
return CoroutinesUtils.invokeSuspendingFunction(coroutineContext, method, callback.getTarget(), callback.getArguments());
|
||||
|
||||
Reference in New Issue
Block a user