|
20 | 20 | import java.lang.reflect.Method;
|
21 | 21 | import java.lang.reflect.Modifier;
|
22 | 22 | import java.lang.reflect.UndeclaredThrowableException;
|
| 23 | +import java.util.ArrayList; |
23 | 24 | import java.util.Collections;
|
24 | 25 | import java.util.List;
|
25 | 26 | import java.util.Map;
|
@@ -335,36 +336,39 @@ private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
|
335 | 336 | new HashCodeInterceptor(this.advised)
|
336 | 337 | };
|
337 | 338 |
|
338 |
| - Callback[] callbacks; |
339 |
| - |
340 | 339 | // If the target is a static one and the advice chain is frozen,
|
341 | 340 | // then we can make some optimizations by sending the AOP calls
|
342 | 341 | // direct to the target using the fixed chain for that method.
|
343 | 342 | if (isStatic && isFrozen) {
|
344 | 343 | Method[] methods = rootClass.getMethods();
|
345 |
| - Callback[] fixedCallbacks = new Callback[methods.length]; |
346 |
| - this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length); |
| 344 | + int methodsCount = methods.length; |
| 345 | + List<Callback> fixedCallbacks = new ArrayList<>(methodsCount); |
| 346 | + this.fixedInterceptorMap = CollectionUtils.newHashMap(methodsCount); |
347 | 347 |
|
348 |
| - // TODO: small memory optimization here (can skip creation for methods with no advice) |
349 |
| - for (int x = 0; x < methods.length; x++) { |
| 348 | + int advicedMethodCount = methodsCount; |
| 349 | + for (int x = 0; x < methodsCount; x++) { |
350 | 350 | Method method = methods[x];
|
| 351 | + //do not create advices for non-overridden methods of java.lang.Object |
| 352 | + if (method.getDeclaringClass() == Object.class) { |
| 353 | + advicedMethodCount--; |
| 354 | + continue; |
| 355 | + } |
351 | 356 | 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); |
| 357 | + fixedCallbacks.add(new FixedChainStaticTargetInterceptor( |
| 358 | + chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass())); |
| 359 | + this.fixedInterceptorMap.put(method, x - (methodsCount - advicedMethodCount) ); |
355 | 360 | }
|
356 | 361 |
|
357 | 362 | // Now copy both the callbacks from mainCallbacks
|
358 | 363 | // and fixedCallbacks into the callbacks array.
|
359 |
| - callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length]; |
| 364 | + Callback[] callbacks = new Callback[mainCallbacks.length + advicedMethodCount]; |
360 | 365 | System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
|
361 |
| - System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length); |
| 366 | + System.arraycopy(fixedCallbacks.toArray(Callback[]::new), 0, callbacks, |
| 367 | + mainCallbacks.length, advicedMethodCount); |
362 | 368 | this.fixedInterceptorOffset = mainCallbacks.length;
|
| 369 | + return callbacks; |
363 | 370 | }
|
364 |
| - else { |
365 |
| - callbacks = mainCallbacks; |
366 |
| - } |
367 |
| - return callbacks; |
| 371 | + return mainCallbacks; |
368 | 372 | }
|
369 | 373 |
|
370 | 374 |
|
|
0 commit comments