如何防止Spring Boot守护程序/服务器应用程序立即关闭/关闭?

我的Spring Boot应用程序不是Web服务器,但它是使用自定义协议的服务器(在本例中使用Camel)。

但Spring Boot在启动后立即停止(优雅地)。 我该如何防止这种情况?

我希望应用程序在Ctrl + C或编程时停止。

@CompileStatic @Configuration class CamelConfig { @Bean CamelContextFactoryBean camelContext() { final camelContextFactory = new CamelContextFactoryBean() camelContextFactory.id = 'camelContext' camelContextFactory } } 

从Apache Camel 2.17开始,有一个更清晰的答案。 引用http://camel.apache.org/spring-boot.html :

要阻止主线程以便Camel保持运行,请包含spring-boot-starter-web依赖项,或者将camel.springboot.main-run-controller = true添加到application.properties或application.yml文件中。

您还需要以下依赖项:

org.apache.camel camel-spring-boot-starter 2.17.0

明确替换2.17.0或使用camel BOM导入依赖关系管理信息以保持一致性。

我找到了解决方案,使用org.springframework.boot.CommandLineRunner + Thread.currentThread().join() ,例如:(注意:下面的代码是在Groovy中,而不是Java)

 package id.ac.itb.lumen.social import org.slf4j.LoggerFactory import org.springframework.boot.CommandLineRunner import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication @SpringBootApplication class LumenSocialApplication implements CommandLineRunner { private static final log = LoggerFactory.getLogger(LumenSocialApplication.class) static void main(String[] args) { SpringApplication.run LumenSocialApplication, args } @Override void run(String... args) throws Exception { log.info('Joining thread, you can press Ctrl+C to shutdown application') Thread.currentThread().join() } } 

使用CountDownLatch的示例实现:

 @Bean public CountDownLatch closeLatch() { return new CountDownLatch(1); } public static void main(String... args) throws InterruptedException { ApplicationContext ctx = SpringApplication.run(MyApp.class, args); final CountDownLatch closeLatch = ctx.getBean(CountDownLatch.class); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { closeLatch.countDown(); } }); closeLatch.await(); } 

现在要停止应用程序,您可以从控制台查找进程ID并发出kill命令:

 kill  

Spring Boot将运行应用程序的任务留给了实现应用程序的协议。 例如,请参阅本指南 :

还需要一些管家对象,如CountDownLatch以保持主线程活着…

因此,运行Camel服务的方式是将Camel作为主Spring Boot应用程序类中的独立应用程序运行。

我的项目是NON WEB Spirng Boot。 我优雅的解决方案是通过CommandLineRunner创建一个守护程序线程。 然后,应用程序不会立即关闭。

  @Bean public CommandLineRunner deQueue() { return args -> { Thread daemonThread; consumer.connect(3); daemonThread = new Thread(() -> {`enter code here` try { consumer.work(); } catch (InterruptedException e) { logger.info("daemon thread is interrupted", e); } }); daemonThread.setDaemon(true); daemonThread.start(); }; } 

为了在不部署Web应用程序时保持Java进程处于活动状态,请将webEnvironment属性设置为false,如下所示:

  SpringApplication sa = new SpringApplication(); sa.setWebEnvironment(false); //important ApplicationContext ctx = sa.run(ApplicationMain.class, args); 

对于springboot应用程序连续运行它必须在一个容器中运行,否则它就像任何java应用程序所有线程完成它完成,你可以添加

  org.springframework.boot spring-boot-starter-web  

它会把它变成webapp,如果没有,你有责任让它在你的实现中保持活力