Mon application Spring Boot n'est pas un serveur Web, mais un serveur utilisant un protocole personnalisé (utilisant Camel dans ce cas).
Mais Spring Boot s'arrête immédiatement (gracieusement) après avoir démarré. Comment puis-je empêcher cela?
Je voudrais que l'application s'arrête si Ctrl + C ou par programme.
@CompileStatic
@Configuration
class CamelConfig {
@Bean
CamelContextFactoryBean camelContext() {
final camelContextFactory = new CamelContextFactoryBean()
camelContextFactory.id = 'camelContext'
camelContextFactory
}
}
Depuis Apache Camel 2.17, la réponse est plus nette. Pour citer http://camel.Apache.org/spring-boot.html :
Pour maintenir le thread principal bloqué afin que Camel reste actif, incluez la dépendance spring-boot-starter-web ou ajoutez camel.springboot.main-run-controller = true à votre fichier application.properties ou application.yml.
Vous voudrez aussi la dépendance suivante:
<dependency>
<groupId>org.Apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>2.17.0</version>
</dependency>
Remplacez clairement <version>2.17.0</version>
ou utilisez la nomenclature chameau pour importer des informations de gestion des dépendances par souci de cohérence.
J'ai trouvé la solution en utilisant org.springframework.boot.CommandLineRunner
+ Thread.currentThread().join()
, par exemple :(note: le code ci-dessous est en Groovy, pas en 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()
}
}
Un exemple d'implémentation utilisant 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();
}
Maintenant, pour arrêter votre application, vous pouvez rechercher l'ID de processus et émettre une commande kill à partir de la console:
kill <PID>
Spring Boot laisse la tâche d’exécuter l’application au protocole autour duquel elle est implémentée. Voir, par exemple, ce guide :
Certains objets de ménage, comme une
CountDownLatch
, sont également nécessaires pour conserver le fil principal en vie ...
Ainsi, la façon d’exécuter un service Camel, par exemple, consisterait à exécuter Camel en tant que application autonome à partir de votre classe d’application Spring Boot principale.
Tous les threads sont terminés, le programme se fermera automatiquement . Ainsi, enregistrer une tâche vide avec @Scheduled
créera un thread en boucle pour empêcher l'arrêt.
Mon projet est NON WEB Spring Boot . Ma solution élégante consiste à créer un thread démon avec CommandLineRunner . Ensuite, l’application ne s’arrête pas immédiatement.
@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();
};
}