简体   繁体   English

具有两个入口点的 Spring Boot 应用程序:CLI 和 Web 服务

[英]Spring Boot Application with Two Entrypoints: CLI and Web Service

I have a spring-boot-starter application that I created that started as a CommandLineRunner that runs in Kubernetes as a CronJob, something like:我创建了一个 spring-boot-starter 应用程序,它作为 CommandLineRunner 启动,在 Kubernetes 中作为 CronJob 运行,类似于:

@SpringBootApplication
@EnableAutoConfiguration
public class JobApplication implements CommandLineRunner {
  Logger logger = LoggerFactory.getLogger(JobApplication.class);


  public static void main(String[] args) {
    ConfigurableApplicationContext context = SpringApplication.run(JobApplication.class, args);
    context.close();
  }

  @Override
  public void run(String... args) throws Exception {
    // run the job
  }
}

I currently run the application in a Dockerfile like this and everything works fine.我目前在这样的 Dockerfile 中运行该应用程序,一切正常。

CMD java -jar /job/job.jar

In this Application there's some Database code and DTOs that I'd like to use and expose as a Spring Web Service, ideally inside the same codebase so I don't have to create multiple Github repos and Java projects and publish a shared library that both use.在这个应用程序中有一些数据库代码和 DTO,我想使用它们并作为 Spring Web 服务公开,最好在同一个代码库中,这样我就不必创建多个 Github 存储库和 Java 项目并发布一个共享库用。 I'd like to keep it simple and just be able to compile and use them directly.我想保持简单,并且能够直接编译和使用它们。

Is there a way to do that?有没有办法做到这一点? I think I'd need a second WebApplication class, but then I'm not sure how to execute it so it uses that instead of the Job.我想我需要第二个 WebApplication 类,但是我不确定如何执行它,所以它使用它而不是 Job。

If not, is there a recommended approach to do what I want to do (building multiple jars is ok if that's the only way... but I'd really like to keep all the code in the same project)?如果没有,是否有推荐的方法来做我想做的事情(如果这是唯一的方法,构建多个 jar 是可以的……但我真的很想将所有代码保留在同一个项目中)?

Have you tried to try to use @Profile ?您是否尝试过使用@Profile

For example:例如:

@Profile("CMD")
@SpringBootApplication
@EnableAutoConfiguration
public class JobApplication implements CommandLineRunner {
  Logger logger = LoggerFactory.getLogger(JobApplication.class);


  public static void main(String[] args) {
    ConfigurableApplicationContext context = SpringApplication.run(JobApplication.class, args);
    context.close();
  }

  @Override
  public void run(String... args) throws Exception {
    // run the job
  }
}


@Profile("WEB")
@SpringBootApplication
public class WebApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }

}

You can start command line as java -jar /job/job.jar -Dspring.profiles.active=CMD您可以以java -jar /job/job.jar -Dspring.profiles.active=CMD启动命令行

and web with profile WEB.和 web 配置文件 WEB。

Because @Profile is a runtime spring annotation it can't be processed until spring context is loaded, you will have (as you discovered)因为@Profile是一个运行时 spring 注释,所以在加载 spring 上下文之前无法处理它,您将拥有(如您所见)

Unable to find a single main class from the following candidates [my.app.WebApplication, my.app.JobApplication]

For this reason you can start a specific spring boot main class with因此,您可以使用以下命令启动特定的 Spring Boot 主类

-Dstart-class=com.sample.WebApplication

And now it should not load the second because now the @Profile should work现在它不应该加载第二个,因为现在@Profile应该可以工作了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM