I see AbstractAspectJAdvice#calculateArgumentBindings
is synchronized, but if first time the Advice method calculates the argument binding, the next time it can return directly without lock, I think it can prevent some lock competition.
such as:
public final void calculateArgumentBindings() {
// The simple case... nothing to bind.
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
return;
}
synchronized(this) {
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
return;
}
int numUnboundArgs = this.parameterTypes.length;
Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
numUnboundArgs--;
}
else if (maybeBindJoinPointStaticPart(parameterTypes[0])) {
numUnboundArgs--;
}
if (numUnboundArgs > 0) {
// need to bind arguments by name as returned from the pointcut match
bindArgumentsByName(numUnboundArgs);
}
this.argumentsIntrospected = true;
}
}
Comment From: leexgone
We had the same problem! This led to serious performance issues in our system. I had to modify the source code locally to temporarily fix it. We hope this problem can be fixed as soon as possible.
Comment From: sbrannen
- superseded by #28783
Comment From: jhoeller
Reopened for a simpler approach as discussed in my closing comment on #28783: We should be able to drop the synchronization completely since ReflectiveAspectJAdvisorFactory
always performs an early call to calculateArgumentBindings
anyway, covering our standard scenario. I'll resolve this in time for the 5.3.22 release.
Comment From: leexgone
Reopened for a simpler approach as discussed in my closing comment on #28783: We should be able to drop the synchronization completely since
ReflectiveAspectJAdvisorFactory
always performs an early call tocalculateArgumentBindings
anyway, covering our standard scenario. I'll resolve this in time for the 5.3.22 release.
That's a great idea! I'm look forward to the new version.