From 7aed6279a284283f079290f44c5d0eee7bef7cda Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 8 Apr 2022 13:02:36 +0200 Subject: [PATCH] Consistent fallback in case of fast-class generation failure Closes gh-28138 --- .../aop/framework/CglibAopProxy.java | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java index 022cc0fddf2..87fa84d6b98 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -375,6 +375,22 @@ private static boolean implementsInterface(Method method, Set> ifcs) { return false; } + /** + * Invoke the given method with a CGLIB MethodProxy if possible, falling back + * to a plain reflection invocation in case of a fast-class generation failure. + */ + @Nullable + private static Object invokeMethod(@Nullable Object target, Method method, Object[] args, MethodProxy methodProxy) + throws Throwable { + try { + return methodProxy.invoke(target, args); + } + catch (CodeGenerationException ex) { + CglibMethodInvocation.logFastClassGenerationFailure(method); + return AopUtils.invokeJoinpointUsingReflection(target, method, args); + } + } + /** * Process a return value. Wraps a return of {@code this} if necessary to be the * {@code proxy} and also verifies that {@code null} is not returned as a primitive. @@ -425,7 +441,7 @@ public StaticUnadvisedInterceptor(@Nullable Object target) { @Override @Nullable public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { - Object retVal = methodProxy.invoke(this.target, args); + Object retVal = invokeMethod(this.target, method, args, methodProxy); return processReturnType(proxy, this.target, method, retVal); } } @@ -450,7 +466,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy Object oldProxy = null; try { oldProxy = AopContext.setCurrentProxy(proxy); - Object retVal = methodProxy.invoke(this.target, args); + Object retVal = invokeMethod(this.target, method, args, methodProxy); return processReturnType(proxy, this.target, method, retVal); } finally { @@ -478,7 +494,7 @@ public DynamicUnadvisedInterceptor(TargetSource targetSource) { public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object target = this.targetSource.getTarget(); try { - Object retVal = methodProxy.invoke(target, args); + Object retVal = invokeMethod(target, method, args, methodProxy); return processReturnType(proxy, target, method, retVal); } finally { @@ -508,7 +524,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy Object target = this.targetSource.getTarget(); try { oldProxy = AopContext.setCurrentProxy(proxy); - Object retVal = methodProxy.invoke(target, args); + Object retVal = invokeMethod(target, method, args, methodProxy); return processReturnType(proxy, target, method, retVal); } finally { @@ -685,13 +701,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy // it does nothing but a reflective operation on the target, and no hot // swapping or fancy proxying. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); - try { - retVal = methodProxy.invoke(target, argsToUse); - } - catch (CodeGenerationException ex) { - CglibMethodInvocation.logFastClassGenerationFailure(method); - retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); - } + retVal = invokeMethod(target, method, argsToUse, methodProxy); } else { // We need to create a method invocation...