Как предотвратить немедленное закрытие/закрытие приложения Spring Boot daemon/server?
My Spring Загрузочное приложение не является веб-сервером, а сервером с использованием пользовательского протокола (в данном случае используется Camel).
Но Spring После немедленного завершения загрузки (изящно). Как это предотвратить?
Я хочу, чтобы приложение остановилось, если Ctrl + C или программно.
@CompileStatic
@Configuration
class CamelConfig {
@Bean
CamelContextFactoryBean camelContext() {
final camelContextFactory = new CamelContextFactoryBean()
camelContextFactory.id = 'camelContext'
camelContextFactory
}
}
Ответы
Ответ 1
В Apache Camel 2.17 есть более чистый ответ. Чтобы процитировать http://camel.apache.org/spring-boot.html:
Чтобы заблокировать основной поток, чтобы Camel оставался включенным, укажите либо зависимость spring -boot-starter-web, либо добавьте camel.springboot.main-run-controller = true к вашим приложениям или приложениям. yml.
Вам также понадобится следующая зависимость:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>2.17.0</version>
</dependency>
Четко замените <version>2.17.0</version>
или используйте спецификацию верблюда для импорта информации управления зависимостями для согласованности.
Ответ 2
Я нашел решение, используя 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()
}
}
Ответ 3
Пример реализации с использованием 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();
}
Теперь, чтобы остановить приложение, вы можете найти идентификатор процесса и выпустить команду kill из консоли:
kill <PID>
Ответ 4
Spring Загрузка оставляет задачу запуска приложения в протокол, вокруг которого реализовано приложение. См. Например, guide:
Также требуются некоторые домашние объекты, такие как CountDownLatch
, чтобы сохранить основной поток...
Таким образом, способ запуска службы Camel, например, состоял бы в том, чтобы запустить Camel как автономное приложение из вашего основного Spring Класс загрузочного приложения.
Ответ 5
Мой проект - NON WEB Spirng Boot. Мое элегантное решение - создать поток демона с помощью CommandLineRunner. Затем приложение не закрывается сразу.
@Bean
public CommandLineRunner deQueue() {
return args -> {
Thread daemonThread;
consumer.connect(3);
daemonThread = new Thread(() -> {
try {
consumer.work();
} catch (InterruptedException e) {
logger.info("daemon thread is interrupted", e);
}
});
daemonThread.setDaemon(true);
daemonThread.start();
};
}
Ответ 6
Все темы завершены, программа закроется автоматически. Таким образом, зарегистрируйте пустое задание с помощью @Scheduled
создаст поток цикла для предотвращения завершения работы.
Ответ 7
Теперь это стало еще проще.
Просто добавьте camel.springboot.main-run-controller=true
в ваше приложение. camel.springboot.main-run-controller=true
Ответ 8
Чтобы сохранить работоспособность java, когда не развертывание веб-приложения, установите для свойства webEnvironment значение false:
SpringApplication sa = new SpringApplication();
sa.setWebEnvironment(false); //important
ApplicationContext ctx = sa.run(ApplicationMain.class, args);
Ответ 9
для приложения springboot для непрерывного запуска его нужно запускать в контейнере, в противном случае это похоже на любое приложение java, все потоки которого завершаются,
вы можете добавить
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
и он превратит его в webapp, если не вы несете ответственность за его сохранение в своей реализации