Как предотвратить немедленное закрытие/закрытие приложения 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, если не вы несете ответственность за его сохранение в своей реализации