Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring @Order on injected lists: execution order is not startup order

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

@Order can sort multiple beans injected as a List of one interface, but it does not define when those singletons are created.

Download Spring source kit

Make pipeline order explicit

A receipt pipeline runs ownership checks before stock checks. The source fixture declares stock first in the configuration file, yet assigns ownership order 10 and stock order 20. The injected List is checked as ownership, then stock. Sorting by registration order would have produced the opposite result.

A collection injection includes every matching bean unless the dependency is narrowed. Adding a new ReceiptCheck elsewhere can therefore change the pipeline. Assert the final list in a context test and keep each check's side effects visible. Single-bean selection solves a different problem.

Do not use order for initialization

An @Order annotation affects collection ordering and some extension-point ordering. It does not guarantee that one singleton starts before another. Use constructor dependencies or a documented lifecycle relationship when one component genuinely requires another to exist first. Lifecycle ownership covers shutdown as well.

Checked code

Java
@Bean @Order(20) ReceiptCheck stockCheck() { return () -> "stock"; }
@Bean @Order(10) ReceiptCheck ownershipCheck() { return () -> "ownership"; }
@Bean ReceiptPipeline receiptPipeline(List<ReceiptCheck> checks) {
    return new ReceiptPipeline(checks);
}

Verification boundary

The Maven source kit passes WiringAndBindingContractTest.orderedListInjectionDoesNotDependOnDeclarationOrder on its local Spring Boot 4 and Java 21 fixture.

Cost and ownership

Sorting k matching beans costs at most O(k log k) during graph assembly in the general case; executing the pipeline costs the sum of its checks for each receipt. The test establishes local injection order, not thread safety or that checks are idempotent.

Common Mistakes

  • Do not assume source-code declaration order defines the injected pipeline.
  • Do not treat @Order as a singleton startup dependency.
  • Do not add a new matching bean without testing how it changes the list.

Read next

Spring @Primary and @Qualifier: default selection versus an explicit bean, Spring constructor injection: required dependencies stay visible, Spring lifecycle cleanup: close container-owned resources, Spring tests: separate business rules, wiring and transport.

spring
spring-boot
ordered-bean-list-injection
Storage details