skip to content

A teammate annotates individual @Before methods with @Order to sequence them and is confused when nothing changes. What's going on, and what would you tell them?

level: seniorimportance: should knowfreq 25%

answer

  1. @Order on method = silent no-op
  2. precedence is per aspect bean
  3. merge or split
  4. ordering as coupling smell

basics

~20 s

@Order controls precedence between aspect beans, not between advice methods. On a method it's ignored for AOP ordering. To sequence steps, put them in separate aspect classes and order those, or combine them into one advice method.

solid answer

~40 s

AOP precedence is a property of the aspect bean, resolved via @Order or the Ordered interface on the class. Placing @Order on an advice method does nothing for join-point ordering — Spring doesn't read it there. So two @Before methods, even with @Order(1) and @Order(2), stay in their default (and for same-type-same-aspect, non-deterministic) order. The fix depends on intent: if the two steps are conceptually one concern, merge them into a single @Before method and control order with plain statement order. If they're distinct cross-cutting concerns, promote each into its own @Aspect class and annotate the classes with @Order. That's the only supported lever. I'd also flag that relying on advice ordering at all is a smell worth questioning — often the coupling should be made explicit in code.

code

java · 15 lines
java
// Broken intent:
@Aspect @Component
class AuditAspect {
    @Order(1) @Before("execution(* svc.*(..))") void first() {}  // @Order ignored
    @Order(2) @Before("execution(* svc.*(..))") void second() {} // @Order ignored
}

// Fix A - one concern, one method, explicit order:
@Aspect @Component
class AuditAspect2 {
    @Before("execution(* svc.*(..))")
    void audit() { first(); second(); }
    private void first() {}
    private void second() {}
}

go deeper

for a junior

May not know it's ignored; learns @Order is class-level.

for a middle

Identifies it as a no-op and suggests separate aspects.

for a senior

Offers both merge and split fixes and questions whether ordering is the right tool.

for a principal

Treats cross-aspect ordering dependence as a design smell and pushes explicit control flow.

## The misconception Developers see `@Order` and assume it is a general 'run this before that' knob. In Spring AOP it specifically ranks **aspect beans** relative to each other at a shared join point. The precedence source is: - `@Order(value)` on the `@Aspect`/`@Component` **class**, or - the class implementing `org.springframework.core.Ordered` (`int getOrder()`). Spring's advice-ordering machinery reads precedence **per aspect**, so `@Order` on a `@Before`/`@Around` **method** is simply not consulted for join-point ordering. The code compiles and runs; it just has no ordering effect — a silent no-op, which is why it's confusing. ## Why it can't work per method All advice in a single `@Aspect` share that aspect's precedence. Within the aspect, ordering is by advice *type* (since 5.2.7) and otherwise undefined for same-typed methods, because declaration order isn't reliably recoverable via reflection. There's no per-method precedence slot in the model. ## The fixes 1. **Merge**: if the two `@Before` bodies are really one concern, write one method and order the statements yourself. Simplest and most readable. 2. **Split + order**: if they're genuinely separate concerns, extract each into its own `@Aspect` class and annotate the classes with `@Order`. Now precedence is honoured. ## Broader advice Heavy reliance on inter-aspect ordering couples independent concerns. Where correctness depends on 'A before B', consider whether that sequencing belongs in explicit code rather than being an emergent property of proxy nesting. Ordering is great for coarse concerns (security outermost, logging near the edge), less great as a substitute for real control flow. ## Interview signal The crisp answer: '`@Order` is class-level; on a method it's ignored — move the steps into separate ordered aspects or into one method.'

  • Does implementing Ordered on the aspect class have the same effect as @Order on the class?
    Yes. Ordered.getOrder() and @Order(value) on the aspect class are equivalent ways to set the same precedence; lower value = higher precedence.

saying these in an interview costs you the question

  • Thinking @Order on a method is a compile error (it's a silent no-op)
  • Believing there is a per-advice-method precedence
  • Suggesting method-name ordering conventions as a real solution

context