Skip to content

Commit b91179d

Browse files
stsypanovsnicoll
authored andcommitted
Skip non-overridden methods of Object.class
See gh-24649
1 parent 21613ea commit b91179d

File tree

1 file changed

+31
-16
lines changed

1 file changed

+31
-16
lines changed

spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java

+31-16
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.lang.reflect.Method;
2121
import java.lang.reflect.Modifier;
2222
import java.lang.reflect.UndeclaredThrowableException;
23+
import java.util.ArrayList;
2324
import java.util.Collections;
2425
import java.util.List;
2526
import java.util.Map;
@@ -330,43 +331,57 @@ private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
330331
aopInterceptor, // for normal advice
331332
targetInterceptor, // invoke target without considering advice, if optimized
332333
new SerializableNoOp(), // no override for methods mapped to this
333-
targetDispatcher, this.advisedDispatcher,
334+
targetDispatcher,
335+
this.advisedDispatcher,
334336
new EqualsInterceptor(this.advised),
335337
new HashCodeInterceptor(this.advised)
336338
};
337339

338-
Callback[] callbacks;
339-
340340
// If the target is a static one and the advice chain is frozen,
341341
// then we can make some optimizations by sending the AOP calls
342342
// direct to the target using the fixed chain for that method.
343343
if (isStatic && isFrozen) {
344344
Method[] methods = rootClass.getMethods();
345-
Callback[] fixedCallbacks = new Callback[methods.length];
346-
this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
345+
int methodsCount = methods.length;
346+
ArrayList<Callback> fixedCallbacks = new ArrayList<>(methodsCount);
347+
this.fixedInterceptorMap = CollectionUtils.newHashMap(methodsCount);
347348

348-
// TODO: small memory optimization here (can skip creation for methods with no advice)
349-
for (int x = 0; x < methods.length; x++) {
349+
int advicedMethodCount = methodsCount;
350+
for (int x = 0; x < methodsCount; x++) {
350351
Method method = methods[x];
352+
//do not create advices for non-overridden methods of java.lang.Object
353+
if (notOverriddenOfObject(method)) {
354+
advicedMethodCount--;
355+
continue;
356+
}
351357
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
352-
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
353-
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
354-
this.fixedInterceptorMap.put(method, x);
358+
fixedCallbacks.add(new FixedChainStaticTargetInterceptor(
359+
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass()));
360+
this.fixedInterceptorMap.put(method, x - (methodsCount - advicedMethodCount) );
355361
}
356362

357363
// Now copy both the callbacks from mainCallbacks
358364
// and fixedCallbacks into the callbacks array.
359-
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
365+
Callback[] callbacks = new Callback[mainCallbacks.length + advicedMethodCount];
360366
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
361-
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
367+
System.arraycopy(fixedCallbacks.toArray(), 0, callbacks, mainCallbacks.length, advicedMethodCount);
362368
this.fixedInterceptorOffset = mainCallbacks.length;
369+
return callbacks;
363370
}
364-
else {
365-
callbacks = mainCallbacks;
366-
}
367-
return callbacks;
371+
372+
return mainCallbacks;
368373
}
369374

375+
/**
376+
* Returns true if param is inherited from {@link Object} and not overridden in declaring class.
377+
* We use this to detect {@link Object#notify()}, {@link Object#notifyAll()}, {@link Object#getClass()} etc.
378+
* to skip creation of useless advices for them.
379+
* @param method to be checked
380+
* @return true in case {@code method} belongs to {@link Object}
381+
*/
382+
private static boolean notOverriddenOfObject(Method method) {
383+
return method.getDeclaringClass() == Object.class;
384+
}
370385

371386
@Override
372387
public boolean equals(@Nullable Object other) {

0 commit comments

Comments
 (0)