When using introduction advisors, the equals method of org.springframework.aop.framework.Cglib2AopProxy$P roxyCallbackFilter will always return false, because it calls the following method:
Code:
private boolean equalsPointcuts(Advisor a, Advisor b) {
return (a instanceof PointcutAdvisor && b instanceof PointcutAdvisor
&& ObjectUtils.nullSafeEquals(((PointcutAdvisor) a).getPointcut(), ((PointcutAdvisor) b).getPointcut()));
}
This method may only return true if the advisors inherit from PointcutAdvisor. As mentioned by Alex in this thread, Cglib2AopProxy$ProxyCallbackFilter.equals returning false will prevent CGLIB from using its class cache.
As an example, the following code will eventually cause an "java.lang.OutOfMemoryError: PermGen space" error:
Code:
public void testOutOfPermGenMemoryDuringProxyCreation()
{
Target target = new Target();
for (int i = 0; i < 10000; i++)
{
ProxyFactory pf = new ProxyFactory();
pf.setTarget(target);
//forces CGLIB use
pf.setProxyTargetClass(true);
Advice advice = new DelegatingIntroductionInterceptor(new SomeInterfaceImpl());
Advisor advisor = new DefaultIntroductionAdvisor(advice);
pf.addAdvisor(advisor);
SomeInterface proxy = (SomeInterface) pf.getProxy();
proxy.doSomething();
}
}
public static class Target
{
}
private static interface SomeInterface
{
public void doSomething();
}
private static class SomeInterfaceImpl implements SomeInterface
{
public void doSomething()
{
System.out.println("something");
}
}
The method introduceInterfaces in class DynamicBeanIntroductor (from Spring Modules) has a code very similar to this test and will probably cause the same error, if executed many times:
Code:
public class DynamicBeanIntroductor extends AbstractDynamicIntroductor {
public Object introduceInterfaces(Object target, Class[] introducedInterfaces) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setProxyTargetClass(true);
proxyFactory.addAdvisor(new BeanIntroductorAdvisor(introducedInterfaces));
proxyFactory.setTarget(target);
return proxyFactory.getProxy();
}
Valdo Noronha