SpringApplication.run运行所有CommandLineRunner bean

时间:2018-11-01 20:02:32

标签: spring-boot

我有一个包含多个main类的项目。这是一个(简体):

@SpringBootApplication
public class ModelStaging implements CommandLineRunner
{
    public static void main(String[] args)
    {
        SpringApplication.run(ModelStaging.class, args);
    }

    @Override
    public void run(String... args) throws Exception
    {
        /* lots of code omitted */
    }
}

我发现的是,运行它们中的任何一个都会触发所有它们的run方法!

也出乎意料:我的项目还包含一个用于启动RESTful服务的类。启动服务还会调用每个run类的每个SpringBootApplication方法。

(请注意,类似的事情反过来发生:当我运行任何命令行实用程序时,也会发现RESTful服务bean,并且该服务开始运行。至少我理解并且应该已经看到了!)

这是预期的行为吗?它记录在任何地方吗?如果不控制调用谁的SpringApplication.run方法,则run的类参数的目的是什么?

自然地,我可以重组软件包和/或组件扫描,以使各个SpringBootApplication类不会彼此发现(并且在它们不应该发现RESTful服务bean时也不会发现它们),但是我d想更好地理解这一点。谢谢!

2 个答案:

答案 0 :(得分:1)

SpringApplication.runCommandLineRunner.run完全没有关系,它们恰好具有相同的名称。 https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-command-line-runner的文档中提到了该接口的多种实现,因此可以从那里推断出所有实现都将被执行。

另外,您的示例中SpringApplication.run(Model.class, args)中的类名只是告诉Spring在哪个类中查找@SpringBootApplication批注。

也不需要在与CommandLineRunner实施相同的类中具有main方法。

答案 1 :(得分:1)

SpringBootApplication注释是什么意思? (强调是我的)

  

表示一个配置类,该配置类声明一个或多个@Bean   方法,并触发自动配置和组件扫描。   这是一个方便注释,等效于声明   @ Configuration,@ EnableAutoConfiguration和@ComponentScan

因此,用它注释多个类将因此实例化多个配置/ bean实例。

CommandLineRunner接口的作用是什么? (强调是我的)

  

接口,用于指示包含该bean时应运行   在SpringApplication中。可以使用多个CommandLineRunner bean   在同一应用程序上下文中定义,可以使用以下命令进行排序   Ordered接口或@Order批注。

所以实际注意到的行为是预期的行为。
无论您以何种方式运行应用程序,都会实例化所有SpringBootApplication Bean,并且您无需显式调用run()即可运行它们。

要实现所需的功能(排除一些bean,包括一些其他bean),可以使用Spring Boot配置文件。