|
|
|
@ -172,7 +172,7 @@ class CglibAopProxy implements AopProxy, Serializable { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Validate the class, writing log messages as necessary.
|
|
|
|
// Validate the class, writing log messages as necessary.
|
|
|
|
validateClassIfNecessary(proxySuperClass); |
|
|
|
validateClassIfNecessary(proxySuperClass, classLoader); |
|
|
|
|
|
|
|
|
|
|
|
// Configure CGLIB Enhancer...
|
|
|
|
// Configure CGLIB Enhancer...
|
|
|
|
Enhancer enhancer = createEnhancer(); |
|
|
|
Enhancer enhancer = createEnhancer(); |
|
|
|
@ -239,11 +239,11 @@ class CglibAopProxy implements AopProxy, Serializable { |
|
|
|
* Checks to see whether the supplied {@code Class} has already been validated and |
|
|
|
* Checks to see whether the supplied {@code Class} has already been validated and |
|
|
|
* validates it if not. |
|
|
|
* validates it if not. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private void validateClassIfNecessary(Class<?> proxySuperClass) { |
|
|
|
private void validateClassIfNecessary(Class<?> proxySuperClass, ClassLoader proxyClassLoader) { |
|
|
|
if (logger.isWarnEnabled()) { |
|
|
|
if (logger.isInfoEnabled()) { |
|
|
|
synchronized (validatedClasses) { |
|
|
|
synchronized (validatedClasses) { |
|
|
|
if (!validatedClasses.containsKey(proxySuperClass)) { |
|
|
|
if (!validatedClasses.containsKey(proxySuperClass)) { |
|
|
|
doValidateClass(proxySuperClass); |
|
|
|
doValidateClass(proxySuperClass, proxyClassLoader); |
|
|
|
validatedClasses.put(proxySuperClass, Boolean.TRUE); |
|
|
|
validatedClasses.put(proxySuperClass, Boolean.TRUE); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -251,19 +251,28 @@ class CglibAopProxy implements AopProxy, Serializable { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Checks for final methods on the {@code Class} and writes warnings to the log |
|
|
|
* Checks for final methods on the given {@code Class}, as well as package-visible |
|
|
|
* for each one found. |
|
|
|
* methods across ClassLoaders, and writes warnings to the log for each one found. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private void doValidateClass(Class<?> proxySuperClass) { |
|
|
|
private void doValidateClass(Class<?> proxySuperClass, ClassLoader proxyClassLoader) { |
|
|
|
if (logger.isWarnEnabled()) { |
|
|
|
if (!Object.class.equals(proxySuperClass)) { |
|
|
|
Method[] methods = proxySuperClass.getMethods(); |
|
|
|
Method[] methods = proxySuperClass.getDeclaredMethods(); |
|
|
|
for (Method method : methods) { |
|
|
|
for (Method method : methods) { |
|
|
|
if (!Object.class.equals(method.getDeclaringClass()) && !Modifier.isStatic(method.getModifiers()) && |
|
|
|
int mod = method.getModifiers(); |
|
|
|
Modifier.isFinal(method.getModifiers())) { |
|
|
|
if (!Modifier.isStatic(mod)) { |
|
|
|
logger.warn("Unable to proxy method [" + method + "] because it is final: " + |
|
|
|
if (Modifier.isFinal(mod)) { |
|
|
|
"All calls to this method via a proxy will be routed directly to the proxy."); |
|
|
|
logger.info("Unable to proxy method [" + method + "] because it is final: " + |
|
|
|
|
|
|
|
"All calls to this method via a proxy will NOT be routed to the target instance."); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) && !Modifier.isPrivate(mod) && |
|
|
|
|
|
|
|
proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) { |
|
|
|
|
|
|
|
logger.info("Unable to proxy method [" + method + "] because it is package-visible " + |
|
|
|
|
|
|
|
"across different ClassLoaders: All calls to this method via a proxy will " + |
|
|
|
|
|
|
|
"NOT be routed to the target instance."); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -604,7 +613,7 @@ class CglibAopProxy implements AopProxy, Serializable { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable { |
|
|
|
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable { |
|
|
|
|
|
|
|
|
|
|
|
private AdvisedSupport advised; |
|
|
|
private final AdvisedSupport advised; |
|
|
|
|
|
|
|
|
|
|
|
public DynamicAdvisedInterceptor(AdvisedSupport advised) { |
|
|
|
public DynamicAdvisedInterceptor(AdvisedSupport advised) { |
|
|
|
this.advised = advised; |
|
|
|
this.advised = advised; |
|
|
|
@ -622,8 +631,8 @@ class CglibAopProxy implements AopProxy, Serializable { |
|
|
|
oldProxy = AopContext.setCurrentProxy(proxy); |
|
|
|
oldProxy = AopContext.setCurrentProxy(proxy); |
|
|
|
setProxyContext = true; |
|
|
|
setProxyContext = true; |
|
|
|
} |
|
|
|
} |
|
|
|
// May be null Get as late as possible to minimize the time we
|
|
|
|
// May be null. Get as late as possible to minimize the time we
|
|
|
|
// "own" the target, in case it comes from a pool.
|
|
|
|
// "own" the target, in case it comes from a pool...
|
|
|
|
target = getTarget(); |
|
|
|
target = getTarget(); |
|
|
|
if (target != null) { |
|
|
|
if (target != null) { |
|
|
|
targetClass = target.getClass(); |
|
|
|
targetClass = target.getClass(); |
|
|
|
@ -689,13 +698,13 @@ class CglibAopProxy implements AopProxy, Serializable { |
|
|
|
|
|
|
|
|
|
|
|
private final MethodProxy methodProxy; |
|
|
|
private final MethodProxy methodProxy; |
|
|
|
|
|
|
|
|
|
|
|
private boolean protectedMethod; |
|
|
|
private final boolean publicMethod; |
|
|
|
|
|
|
|
|
|
|
|
public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments, |
|
|
|
public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments, |
|
|
|
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) { |
|
|
|
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) { |
|
|
|
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers); |
|
|
|
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers); |
|
|
|
this.methodProxy = methodProxy; |
|
|
|
this.methodProxy = methodProxy; |
|
|
|
this.protectedMethod = Modifier.isProtected(method.getModifiers()); |
|
|
|
this.publicMethod = Modifier.isPublic(method.getModifiers()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -704,11 +713,11 @@ class CglibAopProxy implements AopProxy, Serializable { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected Object invokeJoinpoint() throws Throwable { |
|
|
|
protected Object invokeJoinpoint() throws Throwable { |
|
|
|
if (this.protectedMethod) { |
|
|
|
if (this.publicMethod) { |
|
|
|
return super.invokeJoinpoint(); |
|
|
|
return this.methodProxy.invoke(this.target, this.arguments); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
return this.methodProxy.invoke(this.target, this.arguments); |
|
|
|
return super.invokeJoinpoint(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -829,8 +838,8 @@ class CglibAopProxy implements AopProxy, Serializable { |
|
|
|
// of the target type. If so we know it never needs to have return type
|
|
|
|
// of the target type. If so we know it never needs to have return type
|
|
|
|
// massage and can use a dispatcher.
|
|
|
|
// massage and can use a dispatcher.
|
|
|
|
// If the proxy is being exposed, then must use the interceptor the
|
|
|
|
// If the proxy is being exposed, then must use the interceptor the
|
|
|
|
// correct one is already configured. If the target is not static cannot
|
|
|
|
// correct one is already configured. If the target is not static, then
|
|
|
|
// use a Dispatcher because the target can not then be released.
|
|
|
|
// cannot use a dispatcher because the target cannot be released.
|
|
|
|
if (exposeProxy || !isStatic) { |
|
|
|
if (exposeProxy || !isStatic) { |
|
|
|
return INVOKE_TARGET; |
|
|
|
return INVOKE_TARGET; |
|
|
|
} |
|
|
|
} |
|
|
|
|