Spring Boot中CommandLineRunner工作原理及参数问题解析
Spring Boot CommandLineRunner 常见疑问解答
问题1:第一段代码里CommandLineRunner的工作机制是什么?标注@Bean的demo方法由谁调用?
工作机制
Spring Boot的启动流程是这样的:
- 先完成整个Spring上下文的初始化,把所有Bean加载、实例化完毕。
- 上下文就绪后,会自动扫描容器中所有实现了
CommandLineRunner接口的Bean。 - 如果存在多个这类Bean,会按照
@Order注解指定的优先级排序(没加@Order就按Bean注册的先后顺序),然后依次调用它们的run(String... args)方法——这里的args就是你启动应用时在命令行输入的参数。
@Bean方法的调用方
带@Bean注解的demo方法是Spring容器主动调用的。当Spring扫描到这个方法时,会在容器初始化阶段执行它,把方法返回的CommandLineRunner对象纳入容器管理,等上下文启动完成后,就会按上面的逻辑触发run方法。
问题2:运行第二段代码后,main方法能获取命令行参数,但demo方法的args中无参数,这是为什么?
核心原因就是:你在main方法里启动Spring Boot时,没把main拿到的命令行参数传给SpringApplication。
举个常见的错误写法:
public static void main(String[] args) { // main里能拿到args,因为这是JVM直接传递的 System.out.println("main args: " + Arrays.toString(args)); // 这里没把args传给run方法,Spring容器无法获取到参数 SpringApplication.run(YourApplication.class); }
正确的写法必须把args传递给SpringApplication的run方法:
public static void main(String[] args) { System.out.println("main args: " + Arrays.toString(args)); // 把args传入,Spring才会将参数传递给CommandLineRunner SpringApplication.run(YourApplication.class, args); }
CommandLineRunner的run方法拿到的参数,是从Spring Boot维护的启动参数集合中获取的。如果启动时没把main的args传进去,这个集合就是空的,demo方法的args自然没有值;而main方法的args是JVM直接传递的,和Spring容器无关,所以能正常拿到。
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

