|
From: Rod J. <rod...@in...> - 2003-11-28 14:51:12
|
Chris,
I'm sure you can help with this one.
I guessed that the CGLIB MethodFilter interface was what I needed to get
CGLIB override to get only those methods with advice overloaded. However,
when I do that I find that behavior changes.
Here's how I've changed the inner classes in
org.springframework.aop.framework.AopProxy. I want only methods that have an
advice chain to be proxied.
private class CglibProxyFactory {
private Object createProxy() {
try {
return Enhancer.enhance(advised.getTarget().getClass(),
completeProxiedInterfaces(),
new MethodInterceptor() {
public Object intercept(Object handler, Method method, Object[]
objects, MethodProxy methodProxy) throws Throwable {
return invoke(handler, method, objects);
}
},
// I've added the three following arguments
null, // ClassLoader: use default
null, // Method replace: what does this mean? I couldn't work out from
CGLIB Javadoc
new SelectiveOverrideMethodFilter()
);
}
catch (CodeGenerationException ex) {
throw new AspectException("Couldn't generate CGLIB subclass of class '"
+ advised.getTarget().getClass() + "': " +
"Common causes of this problem include using a final class, or a
non-visible class", ex);
}
}
}
private class SelectiveOverrideMethodFilter implements MethodFilter {
public boolean accept(Member member) {
// Proxy is not yet available, but that shouldn't matter
//List chain =
advised.getAdvisorChainFactory().getInterceptorsAndDynamicInterceptionAdvice
(advised, null, (Method) member, advised.getTarget().getClass());
//return !chainIsOptimizableToDirectTargetInvocation(chain);
return true;
}
}
The two lines I've commented out in the accept() method produce a 2.5x
performance improvement in non-advised methods (as you'd expect) but they
also produce different behavior, compared to returning true.
It appears that now CGLIB is creating a new instance of the target and
somehow now copying its state. Previously a property I'd set on the target
was visible through the proxy; now it isn't.
Overall I really like CGLIB: it does what I expect of it with no fuss, and
it's a cool concept. But the Javadoc really is inadequate.
Regards,
Rod
|