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.
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.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.