skip to content

You have two Spring aspects that both match the same method call. By default, which one runs first, and how do you control the order?

level: juniorimportance: should knowfreq 55%

answer

  1. @Order / Ordered on the class
  2. lowest value = outermost
  3. default order undefined
  4. onion layers around target

basics

~20 s

By default the order is undefined. To make it deterministic, give each aspect a precedence: annotate the aspect class with @Order(n) or implement the Ordered interface. The aspect with the lower number runs first (outermost).

solid answer

~40 s

When two aspects match the same join point, Spring does not guarantee any order unless you specify one. You control it by annotating each @Aspect class with @Order(value) (org.springframework.core.annotation.Order) or by having the aspect implement org.springframework.core.Ordered and returning a value from getOrder(). Precedence is by value: the lowest value wins and becomes the outermost aspect, so its @Before advice runs first and its @After advice runs last. The annotation or interface must be placed on the aspect class (the bean), not on individual advice methods. If you set no order, aspects fall to lowest precedence and their relative order is arbitrary, which is a common source of flaky, environment-dependent behaviour.

code

java · 20 lines
java
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Order(1) // lower value -> higher precedence -> runs first (outermost)
class SecurityAspect {
    @Before("execution(* com.acme.service..*(..))")
    void checkAccess() { /* ... */ }
}

@Aspect
@Component
@Order(2) // runs after SecurityAspect on the 'before' leg
class LoggingAspect {
    @Before("execution(* com.acme.service..*(..))")
    void log() { /* ... */ }
}

go deeper

for a junior

Know that default is undefined and @Order/Ordered on the aspect class fixes it, lower value first.

for a middle

Should also articulate that 'first' means outermost and the after-leg reverses.

for a senior

Should mention HIGHEST/LOWEST_PRECEDENCE constants and that ordering only works class-level.

for a principal

Frames ordering as an explicit contract between cross-cutting concerns, not an accident to be discovered.

## The problem An *aspect* is a Spring bean annotated with `@Aspect` that holds *advice* — methods annotated with `@Before`, `@After`, `@Around`, `@AfterReturning`, or `@AfterThrowing` that wrap matched method calls (*join points*). When more than one aspect matches the **same** method, Spring must decide the order in which the aspects wrap that call. **By default this order is undefined** — Spring makes no promise, and it can differ between runs, JVMs, or classpath scan orders. ## Making it deterministic You assign each aspect a *precedence*. Two equivalent ways, both applied to the **aspect class**: 1. `@Order(value)` — `org.springframework.core.annotation.Order` on the `@Aspect` class. 2. Implement `org.springframework.core.Ordered` and return an int from `getOrder()`. Both carry the same meaning. **Lower value = higher precedence = outermost.** Think of aspects as nested onion layers around the target method: the highest-precedence (lowest-value) aspect is the outermost skin. Its `@Before` runs first on the way in; its `@After`/`@AfterReturning`/`@AfterThrowing` runs last on the way out. ## Constants `Ordered.HIGHEST_PRECEDENCE` = `Integer.MIN_VALUE`; `Ordered.LOWEST_PRECEDENCE` = `Integer.MAX_VALUE`. An aspect with no `@Order` is treated as lowest precedence, and ties between unordered aspects are arbitrary. ## Gotchas - Put `@Order`/`Ordered` on the **aspect class**, never on an advice method — `@Order` on a `@Before` method is ignored for AOP precedence. - "Lower number runs first" is only strictly true for the *before* leg; the *after* leg runs in reverse (outermost last). - Undefined default order is not random-per-call but it is not something you should depend on; always order aspects whose interaction matters (e.g. logging vs security vs transactions).

  • Where must @Order be placed for it to affect aspect precedence?
    On the @Aspect class (the bean). Placing it on an individual advice method has no effect on AOP ordering.

saying these in an interview costs you the question

  • Saying the default order is guaranteed by declaration order or class name
  • Putting @Order on an advice method and expecting it to sequence methods
  • Claiming higher @Order value means runs first

context