Java 基于Spring引导控制台的应用程序是如何工作的?

Java 基于Spring引导控制台的应用程序是如何工作的?,java,console-application,spring-boot,Java,Console Application,Spring Boot,如果我正在开发一个相当简单的基于Spring引导控制台的应用程序,我不确定主执行代码的位置。我应该将其放在公共静态void main(String[]args)方法中,还是让主应用程序类实现CommandLineRunner接口并将代码放在运行(String…args)方法中 我将使用一个示例作为上下文。假设我有以下[基本]应用程序(编码为接口,Spring样式): Application.java GreeterService.java(接口) GreeterServiceImpl.jav

如果我正在开发一个相当简单的基于Spring引导控制台的应用程序,我不确定主执行代码的位置。我应该将其放在
公共静态void main(String[]args)
方法中,还是让主应用程序类实现
CommandLineRunner
接口并将代码放在
运行(String…args)
方法中

我将使用一个示例作为上下文。假设我有以下[基本]应用程序(编码为接口,Spring样式):

Application.java

GreeterService.java(接口)

GreeterServiceImpl.java(实现类)

Application.java的等效Spring引导版本大致如下: GreeterServiceImpl.java(实现类)


您应该有一个标准加载器:

@SpringBootApplication
public class MyDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyDemoApplication.class, args);
    }
}
并使用
@Component
注释实现一个
CommandLineRunner
接口

    @Component
    public class MyRunner implements CommandLineRunner {

       @Override    
       public void run(String... args) throws Exception {

      }
   }
@EnableAutoConfiguration
将执行通常的SpringBoot魔术

更新:

正如@jeton所言,最新的Springboot实现了一个直接的:

spring.main.web-environment=false
spring.main.banner-mode=off

请参见

使用
命令行运行程序
这就是它的设计目的,您还可以创建它的实例并将依赖项注入其中。在您的第一个场景中,这将失败,因为您将无法注入依赖项,或者无法从静态方法访问依赖项。@M.Deinum因此此类基于控制台的应用程序必须实现CommandLineRunner接口作为一般经验法则?这为我提供了足够的清晰性,因为即使是文档也没有关注这一点(可能是因为它对大多数人来说是隐式的!)。理想情况下,您可以创建一个实现此接口的bean(而不是您的
应用程序
类)。它与关注点的分离(启动应用程序并执行逻辑)有关。您是指
GreeterService
[implementation]bean吗?因为我的
应用程序
类仅使用此服务。所以在这一点上已经有了一个分离的关注点,不是吗?不,我不是指那个。在阅读一些文章时,您会不断提到希望您的
应用程序
类实现
CommandLineRunner
接口。您可能不希望这样做,而是在单独的类中这样做。为什么您认为这是使用Spring Boot实现CLI应用程序的正确方法
CommandLineRunner
ApplicationRunner
不仅仅用于CLI应用程序。另外,当您使用其中任何一种方法时,Spring会在启动应用程序的
main
方法之前执行其各自的
run
方法,日志消息
INFO 6961-[restartedMain]org.behrang.rpn.main:startedmain在XX.yyyy秒内(JVM运行的时间为MM.NNN)
出现在您的
CommandLineRunner.run(…)
方法中的代码之后。@Behrang那么正确的方法是什么呢?@Wesam不幸的是,据我所知,没有一种优雅的方法可以做到这一点。这里有一个可能的解决方案:@Behrang这个答案给出了实现此功能的正确方法。我刚刚建议编辑添加到官方示例的链接:在springboot 2中,它是
spring.main.web应用程序类型=none
@EnableAutoConfiguration
public class Application
    // *** Should I bother to implement this interface for this simple app?
    implements CommandLineRunner {

    @Autowired
    private GreeterService greeterService;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        System.out.println(greeterService.greet(args)); // here?
    }

    // Only if I implement the CommandLineRunner interface...
    public void run(String... args) throws Exception {
        System.out.println(greeterService.greet(args)); // or here?
    }
}
@SpringBootApplication
public class MyDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyDemoApplication.class, args);
    }
}
    @Component
    public class MyRunner implements CommandLineRunner {

       @Override    
       public void run(String... args) throws Exception {

      }
   }
spring.main.web-environment=false
spring.main.banner-mode=off