1 Attachment(s)
Mixed ordering of @Before and @After advices does not work
I have prepared an example of mixed AOP advices ordering which can demonstrate that ordering is not applied cross @Before and @After advices.
Just run example.OrderingDemoTest
To change ordering it is enough to play with numbers in example.aop.CheckPrecedence
To see the problem, just uncomment the line with throw new RuntimeException in example.aop.CheckBeforeAspect
As I have debugged the problem is in org.springframework.aop.aspectj.autoproxy.AspectJP recedenceComparator (code snippet):
Code:
boolean oneOrOtherIsAfterAdvice =
(AspectJAopUtils.isAfterAdvice(advisor1) || AspectJAopUtils.isAfterAdvice(advisor2));
boolean oneOrOtherIsBeforeAdvice =
(AspectJAopUtils.isBeforeAdvice(advisor1) || AspectJAopUtils.isBeforeAdvice(advisor2));
if (oneOrOtherIsAfterAdvice && oneOrOtherIsBeforeAdvice) {
return NOT_COMPARABLE;
}
So the question is:
- is this the error or the intention? why this mixed Before-After ordering is disabled by extra code?
- is there any workaround available to make such situation working other than implementing advices as @Around?
Thank you if you bring some more light into this.
1 Attachment(s)
What the order of aspects really means?
I try to bring some light into this problem; because here is some kind of misunderstanding.
The real question here is What the order of aspects really means?
Does it means order of executing of aspect's code? From posts above I could say Andrei thinks that yes. But I must say not exactly!
Aspects are like as onion layers and target is in the core. Aspect which wraps all other aspects around same target has highest precedence and last aspect with lowest precedence wraps just target. Order means just that, independently of aspect's type. Doesn't matter if type of aspect is BeforeAdvice or AfterAdvice, a fact is that aspect with BeforeAdvice can wraps aspect with AfterAdvice and vice versa. That is exactly meaning of order of aspects!
Now I would like to explain how the order of aspects affect execution of advices. Look at the following figure:
Attachment 4965
There are two pseudo sequential diagrams and each represents two calls. For now focus just on first call:
1st - normal flow (without exception)
On the left diagram are aspects ordered that before is first (has higher precedence than after) and on the right diagram are aspects ordered vice versa.
The incoming call from caller in left diagram reach aspect before and immediately executes BeforeAdvice but on right diagram the call reaches aspect after which isn't executed because is of it's type. Then we move to the next aspect according to order (deeper layer), the calling on left diagram reaches aspect after wich also isn't executed; but on right diagram was reached before aspect and that one is executed.
In next step is executed target on both sides. Now, when we are following the response of the 1st call, we can se that the response reach aspect after on left side and executed AfterAdvice, while on right side is reached aspect before which isn't executed (because of it's type). In next step the response reaches aspect before (not executed) on left diagram and it reaches aspect after (and executed) on right diagram. Finally the calls finished when response returns to caller on both diagrams.
I hope that you was able to follow my thoughts, because it's important to understand this issue. We went trough the first call and we where see that code was executed in same order on both diagrams (BeforeAdvice -> Target -> AfterAdvice) - independently of order of aspects. If we understand the order of aspects same way, we can see that AfterAdvice can be never called before BeforeAdvice.
So, why missus think that order of before and after aspects depends?
2st - flow when before aspect throws an exception
Now we try to focus on second call. Imagine that before aspect can throw and exception. If you was able follow my thoughts during first call, then you can easily figure out that the result is different. Order of aspects doesn't affect the order of execution of advices, but it affect if the execution of AfterAdvice is executed or not.
I was very surprised when missus point on extra code in spring framework which disable ordering before and after aspects. It looks that author of that code overlooked the case when before aspect throws an exception. I just thought that before and after aspects implemented in spring are unreliable and I preferred to use always around aspects. But now when missus found the very essence of the problem I suggest to fix it. According these facts only before and afterReturn aspects are truly independent of aspects oder.