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 85d249ac208f..953a398ff257 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-2014 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. @@ -335,6 +335,21 @@ private Callback[] getCallbacks(Class rootClass) throws Exception { return callbacks; } + /** + * 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. + */ + private static Object invokeMethod(Object target, Method method, Object[] args, MethodProxy methodProxy) + throws Throwable { + try { + return methodProxy.invoke(target, args); + } + catch (CodeGenerationException ex) { + logger.warn("Unable to fast-class invoke method [" + method + "] on target [" + target + "]. Falling back to reflection."); + 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. @@ -391,7 +406,7 @@ public StaticUnadvisedInterceptor(Object target) { @Override 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); } } @@ -414,7 +429,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 { @@ -441,7 +456,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 { @@ -468,7 +483,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 { @@ -637,7 +652,8 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy // Note that the final invoker must be an InvokerInterceptor, so we know // it does nothing but a reflective operation on the target, and no hot // swapping or fancy proxying. - retVal = methodProxy.invoke(target, args); + Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); + retVal = invokeMethod(target, method, argsToUse, methodProxy); } else { // We need to create a method invocation... @@ -705,7 +721,7 @@ public CglibMethodInvocation(Object proxy, Object target, Method method, Object[ @Override protected Object invokeJoinpoint() throws Throwable { if (this.publicMethod) { - return this.methodProxy.invoke(this.target, this.arguments); + return methodProxy.invoke(this.target, this.arguments); } else { return super.invokeJoinpoint();