Browse Source

Add a classpath check for AOP Coroutines/Reactive conversion

Closes gh-32599
pull/32864/head
Sébastien Deleuze 2 years ago
parent
commit
23696b7db8
  1. 5
      spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java
  2. 5
      spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java
  3. 8
      spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java

5
spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java

@ -102,6 +102,9 @@ class CglibAopProxy implements AopProxy, Serializable { @@ -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 { @@ -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]);

5
spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java

@ -75,6 +75,9 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa @@ -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 @@ -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]);
}

8
spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java

@ -28,7 +28,6 @@ import java.util.Set; @@ -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; @@ -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 { @@ -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 { @@ -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…
Cancel
Save