Redémarrage par programme d’une application de démarrage de printemps

Redémarrage par programme d'une application de démarrage de printemps

1. Vue d'ensemble

Dans ce didacticiel, nous allons montrer commentprogrammatically restart a Spring Boot application.

Redémarrer notre application peut être très pratique dans certains cas:

  • Rechargement de fichiers de configuration lors de la modification de certains paramètres

  • Changer le profil actif au moment de l'exécution

  • Réinitialisation du contexte d'application pour une raison quelconque

Bien que cet article couvre la fonctionnalité de redémarrage d'une application Spring Boot, notez que nous avons également un excellent tutoriel surshutting down Spring Boot applications.

Maintenant, explorons différentes manières de mettre en œuvre le redémarrage d'une application Spring Boot.

2. Redémarrer en créant un nouveau contexte

Nous pouvons redémarrer notre application en fermant le contexte de l'application et en créant un nouveau contexte à partir de zéro. Bien que cette approche soit assez simple, il faut faire attention à certains détails délicats.

Voyons comment implémenter cela dans la méthodemain de notre application Spring Boot:

@SpringBootApplication
public class Application {

    private static ConfigurableApplicationContext context;

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

    public static void restart() {
        ApplicationArguments args = context.getBean(ApplicationArguments.class);

        Thread thread = new Thread(() -> {
            context.close();
            context = SpringApplication.run(Application.class, args.getSourceArgs());
        });

        thread.setDaemon(false);
        thread.start();
    }
}

Comme nous pouvons le voir dans l'exemple ci-dessus, il est important de recréer le contexte dans un thread distinct non-démon - de cette façon, nous empêchons l'arrêt de la JVM, déclenché par la méthodeclose, de fermer notre application. Sinon, notre application s’arrêterait car la machine virtuelle Java n’attend pas la fin des threads du démon avant de les terminer.

De plus, ajoutons un point de terminaison REST par lequel nous pouvons déclencher le redémarrage:

@RestController
public class RestartController {

    @PostMapping("/restart")
    public void restart() {
        Application.restart();
    }
}

Ici, nous avons ajouté un contrôleur avec une méthode de mappage qui appelle notre méthoderestart.

Nous pouvons ensuite appeler notre nouveau point de terminaison pour redémarrer l'application:

curl -X POST localhost:port/restart

Bien sûr, si nous ajoutons un point de terminaison comme celui-ci dans une application réelle, nous devrons également le sécuriser.

3. Point de terminaison de redémarrage de l'actionneur

Une autre façon de redémarrer notre application est d'utiliser lesRestartEndpoint intégrés deSpring Boot Actuator.

Tout d'abord, ajoutons les dépendances Maven requises:


    org.springframework.boot
    spring-boot-starter-actuator


    org.springframework.boot
    spring-cloud-starter

Ensuite, nous devons activer le point de terminaison de redémarrage intégré dans notre fichierapplication.properties:

management.endpoint.restart.enabled=true

Maintenant que nous avons tout mis en place, nous pouvons injecter leRestartEndpoint  dans notre service:

@Service
public class RestartService {

    @Autowired
    private RestartEndpoint restartEndpoint;

    public void restartApp() {
        restartEndpoint.restart();
    }
}

Dans le code ci-dessus, nous utilisons le sbeanRestartEndpoint pour redémarrer notre application. C'est une bonne façon de redémarrer car nous n'avons qu'à appeler une méthode qui fait tout le travail.

Comme nous pouvons le voir, utiliser lesRestartEndpoint est un moyen simple de redémarrer notre application. D'un autre côté, cette approche présente un inconvénient car elle nécessite l'ajout des bibliothèques mentionnées. Si nous ne les utilisons pas déjà, cela peut représenter une surcharge pour cette fonctionnalité uniquement. Dans ce cas, nous pouvons nous en tenir à l'approche manuelle de la section précédente, car elle ne nécessite que quelques lignes de code supplémentaires.

4. Actualisation du contexte de l'application

Dans certains cas, nous pouvons recharger le contexte de l'application en appelant sa méthoderefresh.

Bien que cette méthode puisse paraître prometteuse, seuls certains types de contexte d'application prennent en charge l'actualisation d'un contexte déjà initialisé. Par exemple,FileSystemXmlApplicationContext,GroovyWebApplicationContext, et quelques autres le prennent en charge.

Malheureusement, si nous essayons cela dans une application Web Spring Boot, nous obtiendrons l'erreur suivante:

java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts:
just call 'refresh' once

Enfin, bien que certains types de contexte prennent en charge plusieurs actualisations, nous devrions éviter cela. La raison en est que la méthoderefresh est conçue comme une méthode interne utilisée par le framework pour initialiser le contexte d'application.

5. Conclusion

Dans cet article, nous avons exploré différentes manières de redémarrer une application Spring Boot par programme.

Comme toujours, nous pouvons trouver le code source des exemples surGitHub.