Spring beans are not always loaded in the same order. The Spring container has freedom in the way beans are loaded and even in the smallest projects the order changes. Here are some ways to control this Spring bean loading order.

One of the restrictions is a direct dependency between beans via the @Autowired annotation. The following example Spring ensures that the ProductService initialises before the ProductController initialises.

@RestController
public class ProductController {
    
    @Autowired
    private ProductService productService;
    
    ...
}

Controlling the loading order

But what if there is no direct dependency? Suppose there is an event stream outside of the application. You have a publisher bean that pushes an event to the stream and a subscriber bean that reads the events from the stream. The issue is that you want all the events from the publisher read by the subscriber, so the subscriber bean must be initialised first. This can be done with the @DependsOn annotation.

@Configuration
public class BeanLoadingConfig {
 
    @Bean
    @DependsOn("subscriber")
    public PublisherBean publisherBean() {
        return new PublisherBean();
    }
 
    @Bean(name = "subscriber")
    public SubscriberBean subscriberBean() {
        return new SubscriberBean();
    }
}

This matches the description above in that the PublisherBean depends on the SubscriberBean so the SubscriberBean loades first. For the complete example see my project on github. It should output the following to prove our configuration works:

> Subsciber bean loaded
> Publisher bean loaded

If we would remove the @DependsOn annotation we might get the same result. But running the application multiple times shows that this is not always the case. The Spring container decides the order and sometimes this is the order we intended.

Hopefully you can find your way now in the Spring bean loading order chaos. Happy loading!