I've four CommandLineRunner to be executed in a specific order. Two of them are annotated as @Component and the other two are declared as Bean. I used the @Order annotation to specify the execution order but I found an unexpected behavior running the code below:
...
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Bean
@Order(2)
public CommandLineRunner upRunner(){
return args -> log.info("2 - Running upRunner");
}
@Bean
@Order(1)
public CommandLineRunner downRunner(){
return args -> log.info("1 - Running downRunner");
}
}
...
@Component
@Order(4)
public class RightRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
log.info("4 - Running RightRunner");
}
}
...
@Component
@Order(3)
public class LeftRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
log.info("3 - Running LeftRunner");
}
}
The execution does not follow the order specified by the @Order annotation, see the log below:
[INFO ] Started App in 2.988 seconds (JVM running for 3.949)
[INFO ] 3 - Running LeftRunner
[INFO ] 4 - Running RightRunner
[INFO ] 2 - Running upRunner
[INFO ] 1 - Running downRunner
So, it seems that:
- the runners annotated as @Component are executed in the expected order and before the others.
- the runners declared as @Bean are executed in the order they are defined in the App class with no regard of the @Order annotation.
Is there something I miss to enforce the required order? Could someone clarify this behavior, I'm using spring-boot version 2.4.0?
It is also quite strange that Spring is able to properly sort those beans when injected, just adding the Bean below:
...
@Bean
public Object runners(List<CommandLineRunner> runners) throws Exception {
for(int i=0; i<runners.size(); i++){
runners.get(i).run(null);
}
return new Object();
}
the log shows that the injected CommandLineRunner list is sorted according to the @Order annotation:
[INFO ] 1 - Running downRunner
[INFO ] 2 - Running upRunner
[INFO ] 3 - Running LeftRunner
[INFO ] 4 - Running RightRunner
[INFO ] ...
[INFO ] Started App in 2.754 seconds (JVM running for 3.847)
[INFO ] 3 - Running LeftRunner
[INFO ] 4 - Running RightRunner
[INFO ] 2 - Running upRunner
[INFO ] 1 - Running downRunner
Thanks in advance,
Andrea