Backend Development 8 min read

Mastering @Order in Spring Boot 3: Real‑World Examples and Best Practices

This article explains how the @Order annotation and Ordered interfaces control bean, listener, runner, and aspect execution order in Spring Boot 3, providing step‑by‑step code examples, output demonstrations, and guidance on applying ordering to various Spring components.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering @Order in Spring Boot 3: Real‑World Examples and Best Practices

1. Introduction

@Order is a Spring annotation that defines the priority of bean execution; it can be placed on classes, methods, or fields. It only affects the order of beans when they are injected into a collection, not the bean loading or instantiation sequence. A smaller integer value indicates a higher priority. Neither @Order nor the Ordered interface can determine the actual bean loading order, which is decided by the registration (scanning) order.

2. Practical Cases

2.1 Collection Injection

When injecting a collection of beans (e.g., multiple implementations of an interface), @Order can control their order in the collection.

<code>public interface DAO { void save(); }
@Component public class A implements DAO { public void save() { System.out.println("A..."); } }
@Component public class B implements DAO { public void save() { System.out.println("B..."); } }
@Component public class C implements DAO { public void save() { System.out.println("C..."); } }
@Resource private List<DAO> daos;
public void print() { for (DAO dao : daos) { dao.save(); } }</code>

Running the program prints A... , B... , C... . After adding @Order(2) to A , @Order(1) to B , and @Order(0) to C , the output becomes C... , B... , A... . The collection can also be an array; sorting works the same way.

2.2 ApplicationListener Event

Listeners annotated with @Order are invoked according to their order when an event is published.

<code>@Component @Order(-1) public class ListenerA implements ApplicationListener<PackEvent> { @Override public void onApplicationEvent(PackEvent event) { System.out.println("A Listener..."); } }
@Component @Order(-2) public class ListenerB implements ApplicationListener<PackEvent> { @Override public void onApplicationEvent(PackEvent event) { System.out.println("B Listener..."); } }</code>

Publishing PackEvent prints B Listener... followed by A Listener... . Implementing the Ordered interface yields the same effect.

2.3 Application/CommandLineRunner

Runner interfaces execute after the Spring Boot context is fully loaded; @Order determines their execution sequence.

<code>@Component @Order(0) public class RunnerA implements CommandLineRunner { public void run(String... args) { System.out.println("A Runner..."); } }
@Component @Order(-1) public class RunnerB implements CommandLineRunner { public void run(String... args) { System.out.println("B Runner..."); } }</code>

Output: B Runner... then A Runner... . Registration via @Bean or implementing Ordered works as well.

2.4 BeanPostProcessor

BeanPostProcessor can be ordered only by implementing Ordered (or PriorityOrdered ) and returning a custom order value.

<code>public class APostProcessor implements BeanPostProcessor, Ordered { public Object postProcessBeforeInitialization(Object bean, String beanName) { System.out.println("A BeanPostProcessor"); return bean; } public int getOrder() { return -1; } }
public class BPostProcessor implements BeanPostProcessor, Ordered { public Object postProcessBeforeInitialization(Object bean, String beanName) { System.out.println("B BeanPostProcessor"); return bean; } public int getOrder() { return -2; } }</code>

Execution result: B BeanPostProcessor then A BeanPostProcessor . The @Order annotation is not supported for BeanPostProcessor ordering.

2.5 BeanFactoryPostProcessor

Similar to BeanPostProcessor; ordering is controlled by implementing the Ordered interface.

2.6 @Aspect

Aspects can be ordered with @Order or by implementing Ordered .

<code>@Aspect @Order(-1) public static class AspectA { @Pointcut("execution(* *(..))") private void a() {} @Before("a()") public void before() { System.out.println("A before..."); } }
@Aspect @Order(-2) public static class AspectB { @Pointcut("execution(* *(..))") private void b() {} @Before("b()") public void before() { System.out.println("B before..."); } }</code>

Execution order: B before... , A before... , then the target method.

2.7 Other Sortable Components

Components such as FailureAnalyzer , ApplicationContextInitializer , ErrorPageRegistrar , ErrorViewResolver , etc., are also sortable when obtained via SpringFactoriesLoader#load(Class) .

<code>// Any object loaded through SpringFactoriesLoader.load(Class) supports ordering</code>

Images illustrating Runner ordering and aspect execution are retained below.

JavaSpring BootAspectJ@OrderEvent ListenerRunnerBean Ordering
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.