skip to content

When several advice methods in the SAME @Aspect apply to the same join point, in what order do they run?

level: seniorimportance: must knowfreq 50%

answer

  1. type precedence: Around>Before>After>AfterReturning>AfterThrowing
  2. same type = UNDEFINED order
  3. @After = finally, wraps returning/throwing
  4. @Order on method = ignored (only cross-aspect)
  5. fix: merge or split into ordered aspects

basics

~20 s

Within one aspect, advice runs in a fixed precedence by type: @Around, then @Before, then @After, @AfterReturning, @AfterThrowing. But two advices of the SAME type at the same join point have undefined order — you cannot rely on method declaration order.

solid answer

~40 s

Since Spring Framework 5.2.7, when multiple advice methods in the *same* @Aspect target the same join point, they are ordered by **advice type**, highest to lowest: `@Around` > `@Before` > `@After` > `@AfterReturning` > `@AfterThrowing`. One caveat: an `@After` (finally-style) method effectively runs *after* any `@AfterReturning`/`@AfterThrowing` in the same aspect, matching AspectJ's after-finally semantics. The important gotcha: if two advices are of the **same type** and hit the same join point, the ordering is **undefined** — Spring can't recover the source declaration order from javac-compiled bytecode. `@Order` on the advice *method* is ignored; `@Order`/`Ordered` only orders whole aspects relative to each other. The fix is to merge the two same-type advices into one method, or split them into separate aspects and order those aspects.

code

java · 23 lines
java
@Aspect
@Component
public class TracingAspect {

    @Around("execution(* svc..*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        // runs FIRST (highest precedence), wraps everything
        return pjp.proceed();
    }

    @Before("execution(* svc..*(..))")
    public void before() { /* runs after around's 'before' part */ }

    @AfterReturning("execution(* svc..*(..))")
    public void afterReturning() { /* on success */ }

    @After("execution(* svc..*(..))")
    public void afterFinally() { /* runs after afterReturning/afterThrowing */ }

    // NOTE: if you added a SECOND @Before here for the same pointcut,
    // its order relative to before() would be UNDEFINED.
    // @Order on these methods would NOT fix that — it only orders aspects.
}

go deeper

for a junior

Know that @Around wraps and @Before runs before the method; deep ordering not expected.

for a middle

State the type-precedence order and that @After is finally-style.

for a senior

Nail the 'same-type = undefined' gotcha and the correct remedies (merge or split-and-order).

for a principal

Discuss @DeclarePrecedence, the javac reflection limitation behind undefined order, and designing aspects to avoid intra-aspect ambiguity.

**The problem.** Several advice methods can match the *same* join point (same method execution). There are two distinct ordering questions: (a) ordering **within one aspect**, and (b) ordering **across different aspects**. This question is about (a). **Ordering by advice type (Spring 5.2.7+).** Within a single `@Aspect` class, advice methods that apply to the same join point are ordered by their **advice type**, from highest to lowest precedence: 1. `@Around` 2. `@Before` 3. `@After` 4. `@AfterReturning` 5. `@AfterThrowing` Higher precedence means it runs *first* on the way in. Because `@Around` and `@Before` are 'before-like', higher precedence runs earlier. The after-family is 'after-like'. **The @After finally caveat.** `@After` corresponds to AspectJ's *after (finally)* advice — it runs whether the method returned or threw. Spring notes that an `@After` advice method will effectively be invoked **after** any `@AfterReturning` or `@AfterThrowing` methods in the same aspect, matching AspectJ's after-finally semantics. So although the type list places `@After` before the returning/throwing entries in *precedence*, in the actual on-exit invocation the finally-style `@After` wraps around them. **The real gotcha — two advices of the SAME type.** If two `@Before` methods (or two of any single type) both match one join point *inside the same aspect*, the order between them is **undefined**. The Spring reference explicitly states there is no way to retrieve the source declaration order through reflection for javac-compiled classes. So you must **not** depend on the order you wrote the methods in. **Why @Order does not help here.** `@org.springframework.core.annotation.Order` and the `org.springframework.core.Ordered` interface control precedence **between aspects**, not between two advice methods of the same aspect. Putting `@Order` on an individual advice method has no effect on intra-aspect ordering. **How to fix / control it.** The Spring-recommended remedies: - **Collapse** the two same-type advice methods into a single advice method per join point in that aspect (then you control the internal order explicitly in code), or - **Refactor** the pieces of advice into **separate @Aspect classes**, and order those aspects with `@Order`/`Ordered` (or AspectJ's `@DeclarePrecedence`). **Nesting mental model.** For a single join point with a full set of advice, the flow is: around(before part) -> before -> [target method] -> afterReturning/afterThrowing -> after(finally) -> around(after part). The higher-precedence around wraps the whole thing. **Common misconceptions:** believing advice runs top-to-bottom in source order; believing `@Order` on a method reorders advice within an aspect; assuming `@After` always runs before `@AfterReturning`. Getting these wrong leads to subtle bugs where, e.g., a logging `@After` fires around a mutation `@AfterReturning` in an order the candidate didn't expect.

  • Two @Before methods in the same aspect must run in a guaranteed order. How do you achieve it?
    You cannot within one aspect — intra-aspect same-type order is undefined. Either merge them into one @Before method and sequence the logic in code, or move them into two separate aspects and order those with @Order/Ordered.
  • Does @Order on an advice method change ordering within its aspect?
    No. @Order and Ordered only establish precedence between different aspects. On an individual advice method they have no effect on intra-aspect ordering.

saying these in an interview costs you the question

  • Claiming advice runs in source/declaration order within an aspect
  • Thinking @Order on an advice method reorders advice inside the same aspect
  • Saying @After always runs before @AfterReturning/@AfterThrowing
  • Assuming two @Before methods in one aspect have a deterministic order

context