|
From: Rod J. <rod...@in...> - 2003-12-02 11:03:38
|
All, Some more AOP refactoring to be aware of. Motivated partly by performance, but also for clarity and consistency. And more thorough testing. - There's now a new base class, ProxyConfig, to hold bean properties used in AdvisedSupport and other proxy creators such as TransactionProxyFactoryBean. This means that there's more control in creating a TransactionFactory bean, over whether to force CGLIB or enable CGLIB optimizations. Note that the "proxyInterfacesOnly" method is gone: if you set this to false, set the inherited "proxyTargetClass" property to false. This is consistent with AdvisedSupport. - There are now distinct MethodInvocation implementations and AopProxy implementations for dynamic proxies, CGLIB and "optimized CGLIB". Note that there appears to be code duplication here and it would be possible to refactor the invoke or interceptor methods using a template method in the base class, but this would add a distinct performance overhead (I've benchmarked it). As you know, I abhor code duplication and I wouldn't do this without good reason. Having sep class should also help with CGLIB1/2 migration. (We could even autodetect the CGLIB version, as the cost of creating a new proxy isn't usually that significant: it's the cost of using it that matters.) - All the AopProxy tests run for CGLIB, DPs and optimized CGLIB to guarantee consistent behaviour. (Helps to cope with the code duplication also.) Hence you'll note about 50 more tests in the suite, now up to 1103 tests. "CGLIB subclass optimizations" mean that methods with no advice aren't overridden. This gives a 2x performance boost for non-advised methods (excluding the work of the method, which may of course be more significant). However, there are some tradeoffs to be aware of in certain cases: - To do this, the original target is copied fieldwise into the instance of the enhanced class. This means that the original class must have a no-arg constructor. Also if the old target was registered as a listener for other objects, the new class won't be. - This doesn't work with pooling, thread local or other "dynamic" TargetSources: only for a single shared instance - It's impossible to change the target or TargetSource or advice thereafter. So this is a good value optimization for shared objects without unusual requirements: in short, it's safe most of the time. Note that CGLIB performance should be pretty good without this agressive optimization. With its own AopProxy using MethodProxy rather than reflection, CGLIB seems slightly faster than dynamic proxies. Overall, the overhead of AOP in typical usage is probably under half what it was with M3, and 15% of what it was before then. Regards, Rod |