Add a classpath check for AOP Coroutines/Reactive conversion
Closes gh-32599
This commit is contained in:
parent
7b7cfb27a3
commit
23696b7db8
|
@ -102,6 +102,9 @@ class CglibAopProxy implements AopProxy, Serializable {
|
|||
|
||||
private static final String COROUTINES_FLOW_CLASS_NAME = "kotlinx.coroutines.flow.Flow";
|
||||
|
||||
private static final boolean coroutinesReactorPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt",
|
||||
CglibAopProxy.class.getClassLoader());;
|
||||
|
||||
|
||||
/** The configuration used to configure this proxy. */
|
||||
protected final AdvisedSupport advised;
|
||||
|
@ -421,7 +424,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
|||
throw new AopInvocationException(
|
||||
"Null return value from advice does not match primitive return type for: " + method);
|
||||
}
|
||||
if (KotlinDetector.isSuspendingFunction(method)) {
|
||||
if (coroutinesReactorPresent && KotlinDetector.isSuspendingFunction(method)) {
|
||||
return COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, -1).getParameterType().getName()) ?
|
||||
CoroutinesUtils.asFlow(returnValue) :
|
||||
CoroutinesUtils.awaitSingleOrNull(returnValue, arguments[arguments.length - 1]);
|
||||
|
|
|
@ -75,6 +75,9 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
|||
|
||||
private static final String COROUTINES_FLOW_CLASS_NAME = "kotlinx.coroutines.flow.Flow";
|
||||
|
||||
private static final boolean coroutinesReactorPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt",
|
||||
JdkDynamicAopProxy.class.getClassLoader());;
|
||||
|
||||
/** We use a static Log to avoid serialization issues. */
|
||||
private static final Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
|
||||
|
||||
|
@ -234,7 +237,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
|||
throw new AopInvocationException(
|
||||
"Null return value from advice does not match primitive return type for: " + method);
|
||||
}
|
||||
if (KotlinDetector.isSuspendingFunction(method)) {
|
||||
if (coroutinesReactorPresent && KotlinDetector.isSuspendingFunction(method)) {
|
||||
return COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, -1).getParameterType().getName()) ?
|
||||
CoroutinesUtils.asFlow(retVal) : CoroutinesUtils.awaitSingleOrNull(retVal, args[args.length - 1]);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import java.util.Set;
|
|||
import kotlin.coroutines.Continuation;
|
||||
import kotlin.coroutines.CoroutineContext;
|
||||
import kotlinx.coroutines.Job;
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.AopInvocationException;
|
||||
|
@ -65,6 +64,9 @@ import org.springframework.util.ReflectionUtils;
|
|||
*/
|
||||
public abstract class AopUtils {
|
||||
|
||||
private static final boolean coroutinesReactorPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt",
|
||||
AopUtils.class.getClassLoader());;
|
||||
|
||||
/**
|
||||
* Check whether the given object is a JDK dynamic proxy or a CGLIB proxy.
|
||||
* <p>This method additionally checks if the given object is an instance
|
||||
|
@ -347,7 +349,7 @@ public abstract class AopUtils {
|
|||
// Use reflection to invoke the method.
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
return KotlinDetector.isSuspendingFunction(method) ?
|
||||
return coroutinesReactorPresent && KotlinDetector.isSuspendingFunction(method) ?
|
||||
KotlinDelegate.invokeSuspendingFunction(method, target, args) : method.invoke(target, args);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
|
@ -370,7 +372,7 @@ public abstract class AopUtils {
|
|||
*/
|
||||
private static class KotlinDelegate {
|
||||
|
||||
public static Publisher<?> invokeSuspendingFunction(Method method, @Nullable Object target, Object... args) {
|
||||
public static Object invokeSuspendingFunction(Method method, @Nullable Object target, Object... args) {
|
||||
Continuation<?> continuation = (Continuation<?>) args[args.length -1];
|
||||
Assert.state(continuation != null, "No Continuation available");
|
||||
CoroutineContext context = continuation.getContext().minusKey(Job.Key);
|
||||
|
|
Loading…
Reference in New Issue