Two advice methods declared in the same @Aspect class both apply to one join point. What determines their relative order, and how has Spring's behaviour here changed?
answer
- @Order = class level only
- javac loses declaration order
- 5.2.7: order by advice type
- Around>Before>After>AfterReturning>AfterThrowing
- same-type still undefined -> split aspects
basics
~20 sYou cannot order two advice methods within the same aspect via @Order — it only works between aspects. Historically the order was undefined (reflection can't recover source order). Since Spring 5.2.7 they're ordered by advice type: @Around, @Before, @After, @AfterReturning, @AfterThrowing.
solid answer
~40 s@Order and Ordered set precedence at the aspect (class) level, not between individual advice methods, so you can't sequence two @Before methods in the same class with annotations. Originally, when two advice methods in one aspect hit the same join point their order was undefined, because javac doesn't preserve declaration order retrievable via reflection. Spring's guidance was to collapse them into a single advice method or split them into separate, orderable aspect classes. As of Spring Framework 5.2.7, advice methods in the same @Aspect that run at the same join point are assigned precedence by advice type, highest to lowest: @Around, @Before, @After, @AfterReturning, @AfterThrowing — and @After effectively runs after @AfterReturning/@AfterThrowing, matching AspectJ's LIFO semantics for @After. If you truly need deterministic ordering of two same-typed advices, refactor into separate aspects.
code
java · 13 lines// You CANNOT reliably order these two @Before methods within one aspect:
@Aspect @Component
class MixedAspect {
@Before("execution(* svc.*(..))") void a() { /* order vs b() not guaranteed */ }
@Before("execution(* svc.*(..))") void b() { /* ... */ }
}
// Fix: split into two ordered aspects
@Aspect @Component @Order(1)
class FirstAspect { @Before("execution(* svc.*(..))") void a() {} }
@Aspect @Component @Order(2)
class SecondAspect { @Before("execution(* svc.*(..))") void b() {} }go deeper
Likely unaware; enough to know @Order is class-level.
Knows @Order doesn't work per-method and order was undefined.
Knows the 5.2.7 advice-type ordering and the same-type caveat, reaches for refactoring.
Avoids same-aspect ordering dependence entirely; designs one concern per aspect for clarity and testability.
## Aspect-level vs method-level ordering `@Order`/`Ordered` establish precedence **between aspect beans**. There is **no** supported way to attach a precedence to an individual advice method for AOP ordering — `@Order` on a `@Before` method is ignored. So the question 'which of my two `@Before` methods in the same class runs first?' cannot be answered with annotations. ## Why the historical order was undefined Spring discovers advice methods via reflection. For classes compiled by `javac`, **the source declaration order of methods is not guaranteed to be recoverable** through reflection. Consequently, when two advice methods in the same aspect matched the same join point, Spring could not reliably order them, and the reference documentation explicitly called the order **undefined**. The recommended fixes were: 1. **Collapse** the two advices into a single advice method that does both things in the order you want (you control statement order in code), or 2. **Split** them into two separate `@Aspect` classes and order those classes with `Ordered`/`@Order`. ## The Spring 5.2.7 change As of **Spring Framework 5.2.7**, advice methods defined in the **same** `@Aspect` class that need to run at the same join point are assigned precedence **based on advice type**, from highest to lowest precedence: `@Around` → `@Before` → `@After` → `@AfterReturning` → `@AfterThrowing` Important subtlety: an `@After` (finally) advice method is effectively invoked **after** any `@AfterReturning` or `@AfterThrowing` methods in the same aspect, following AspectJ's 'last in, first out' behaviour for `@After`. So on the exit leg you can reason about it, but note the type-based rule only orders **different** advice types — **two methods of the same type** (e.g. two `@Before`) in one aspect are still not deterministically ordered, so the split-into-aspects advice still applies there. ## Practical guidance - Need two `@Before` steps in a strict order? Put them in **two aspects** and use `@Order`, or merge them into one method. - Don't rely on source order or method-name alphabetical order — neither is contractual. - The type-based rule is convenient but knowing it exists is more about avoiding surprises than something to depend on for critical sequencing. ## Interview signal Strong candidates distinguish *between-aspect* ordering (annotation-controlled) from *within-aspect* ordering (type-based since 5.2.7, otherwise undefined) and reach for refactoring rather than fragile tricks.
- Since 5.2.7, does the type-based ordering also decide the order of two @Before methods in the same aspect?No. Type-based ordering only distinguishes different advice types. Two advice methods of the same type in one aspect are still not deterministically ordered — split them into separate aspects or merge them.
- What are the two refactorings Spring recommends when same-aspect order matters?Collapse the pieces of advice into a single advice method per join point, or move them into separate @Aspect classes that you order with Ordered/@Order at the aspect level.
saying these in an interview costs you the question
- Claiming @Order on advice methods sequences them within an aspect
- Assuming source/declaration order is honoured
- Saying 5.2.7 makes all same-aspect advice fully ordered including same-type methods