我有四个CommandLineRunner需要按照特定顺序执行。其中两个被注释为@Component,另外两个被声明为Bean。我使用了@Order注解来指定执行顺序,但是在运行以下代码时发现了意外的行为:
...
@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");
}
}
执行顺序不遵循@Order注解指定的顺序,请参见下面的日志:
[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
因此,看起来:
- 标记为@Component的运行器按预期顺序执行,并在其他运行器之前执行。
- 声明为@Bean的运行器按照在App类中定义的顺序执行,而不考虑@Order注释。
我有什么遗漏以强制执行所需的顺序吗? 有人能澄清这种行为吗?我正在使用spring-boot版本2.4.0?
另外,当注入时,Spring能够正确地对这些bean进行排序,只需添加下面的Bean即可:
...
@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();
}
日志显示注入的CommandLineRunner列表根据@Order注解进行了排序:
[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
谢谢您的提前预约,
安德烈
CommandLineRunner
注释的bean时遇到了相同的问题。 - jumping_monkey