|
38 | 38 | import org.springframework.aop.RawTargetAccess;
|
39 | 39 | import org.springframework.aop.TargetSource;
|
40 | 40 | import org.springframework.aop.support.AopUtils;
|
41 |
| -import org.springframework.cglib.core.ClassGenerator; |
| 41 | +import org.springframework.cglib.core.ClassLoaderAwareGeneratorStrategy; |
42 | 42 | import org.springframework.cglib.core.CodeGenerationException;
|
43 | 43 | import org.springframework.cglib.core.SpringNamingPolicy;
|
44 | 44 | import org.springframework.cglib.proxy.Callback;
|
|
49 | 49 | import org.springframework.cglib.proxy.MethodInterceptor;
|
50 | 50 | import org.springframework.cglib.proxy.MethodProxy;
|
51 | 51 | import org.springframework.cglib.proxy.NoOp;
|
52 |
| -import org.springframework.cglib.transform.impl.UndeclaredThrowableStrategy; |
53 | 52 | import org.springframework.core.SmartClassLoader;
|
54 | 53 | import org.springframework.lang.Nullable;
|
55 | 54 | import org.springframework.util.Assert;
|
56 | 55 | import org.springframework.util.ClassUtils;
|
57 | 56 | import org.springframework.util.ObjectUtils;
|
| 57 | +import org.springframework.util.ReflectionUtils; |
58 | 58 |
|
59 | 59 | /**
|
60 | 60 | * CGLIB-based {@link AopProxy} implementation for the Spring AOP framework.
|
@@ -189,7 +189,7 @@ public Object getProxy(@Nullable ClassLoader classLoader) {
|
189 | 189 | enhancer.setSuperclass(proxySuperClass);
|
190 | 190 | enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
|
191 | 191 | enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
|
192 |
| - enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); |
| 192 | + enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader)); |
193 | 193 |
|
194 | 194 | Callback[] callbacks = getCallbacks(rootClass);
|
195 | 195 | Class<?>[] types = new Class<?>[callbacks.length];
|
@@ -634,8 +634,8 @@ public FixedChainStaticTargetInterceptor(
|
634 | 634 | @Override
|
635 | 635 | @Nullable
|
636 | 636 | public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
637 |
| - MethodInvocation invocation = new CglibMethodInvocation(proxy, this.target, method, args, |
638 |
| - this.targetClass, this.adviceChain, methodProxy); |
| 637 | + MethodInvocation invocation = new CglibMethodInvocation( |
| 638 | + proxy, this.target, method, args, this.targetClass, this.adviceChain, methodProxy); |
639 | 639 | // If we get here, we need to create a MethodInvocation.
|
640 | 640 | Object retVal = invocation.proceed();
|
641 | 641 | retVal = processReturnType(proxy, this.target, method, retVal);
|
@@ -740,6 +740,25 @@ public CglibMethodInvocation(Object proxy, @Nullable Object target, Method metho
|
740 | 740 | methodProxy : null);
|
741 | 741 | }
|
742 | 742 |
|
| 743 | + @Override |
| 744 | + @Nullable |
| 745 | + public Object proceed() throws Throwable { |
| 746 | + try { |
| 747 | + return super.proceed(); |
| 748 | + } |
| 749 | + catch (RuntimeException ex) { |
| 750 | + throw ex; |
| 751 | + } |
| 752 | + catch (Exception ex) { |
| 753 | + if (ReflectionUtils.declaresException(getMethod(), ex.getClass())) { |
| 754 | + throw ex; |
| 755 | + } |
| 756 | + else { |
| 757 | + throw new UndeclaredThrowableException(ex); |
| 758 | + } |
| 759 | + } |
| 760 | + } |
| 761 | + |
743 | 762 | /**
|
744 | 763 | * Gives a marginal performance improvement versus using reflection to
|
745 | 764 | * invoke the target when invoking public methods.
|
@@ -968,52 +987,4 @@ public int hashCode() {
|
968 | 987 | }
|
969 | 988 | }
|
970 | 989 |
|
971 |
| - |
972 |
| - /** |
973 |
| - * CGLIB GeneratorStrategy variant which exposes the application ClassLoader |
974 |
| - * as thread context ClassLoader for the time of class generation |
975 |
| - * (in order for ASM to pick it up when doing common superclass resolution). |
976 |
| - */ |
977 |
| - private static class ClassLoaderAwareUndeclaredThrowableStrategy extends UndeclaredThrowableStrategy { |
978 |
| - |
979 |
| - @Nullable |
980 |
| - private final ClassLoader classLoader; |
981 |
| - |
982 |
| - public ClassLoaderAwareUndeclaredThrowableStrategy(@Nullable ClassLoader classLoader) { |
983 |
| - super(UndeclaredThrowableException.class); |
984 |
| - this.classLoader = classLoader; |
985 |
| - } |
986 |
| - |
987 |
| - @Override |
988 |
| - public byte[] generate(ClassGenerator cg) throws Exception { |
989 |
| - if (this.classLoader == null) { |
990 |
| - return super.generate(cg); |
991 |
| - } |
992 |
| - |
993 |
| - Thread currentThread = Thread.currentThread(); |
994 |
| - ClassLoader threadContextClassLoader; |
995 |
| - try { |
996 |
| - threadContextClassLoader = currentThread.getContextClassLoader(); |
997 |
| - } |
998 |
| - catch (Throwable ex) { |
999 |
| - // Cannot access thread context ClassLoader - falling back... |
1000 |
| - return super.generate(cg); |
1001 |
| - } |
1002 |
| - |
1003 |
| - boolean overrideClassLoader = !this.classLoader.equals(threadContextClassLoader); |
1004 |
| - if (overrideClassLoader) { |
1005 |
| - currentThread.setContextClassLoader(this.classLoader); |
1006 |
| - } |
1007 |
| - try { |
1008 |
| - return super.generate(cg); |
1009 |
| - } |
1010 |
| - finally { |
1011 |
| - if (overrideClassLoader) { |
1012 |
| - // Reset original thread context ClassLoader. |
1013 |
| - currentThread.setContextClassLoader(threadContextClassLoader); |
1014 |
| - } |
1015 |
| - } |
1016 |
| - } |
1017 |
| - } |
1018 |
| - |
1019 | 990 | }
|
0 commit comments