web-dev-qa-db-fra.com

Fermez par programme l'application Spring Boot

Comment puis-je arrêter par programme a Spring Boot application sans mettre fin à la machine virtuelle?

Dans d’autres œuvres, quel est le contraire de

new SpringApplication(Main.class).run(args);
88
Axel Fontaine

Fermer un SpringApplication signifie fondamentalement fermer le ApplicationContext sous-jacent. La méthode SpringApplication#run(String...) vous donne ce ApplicationContext sous la forme d'un ConfigurableApplicationContext. Vous pouvez alors close() vous-même. Par exemple,

@SpringBootApplication
public class Example {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
        // ...determine it's time to shut down...
        ctx.close();
    }
}

Sinon, vous pouvez utiliser la méthode d'assistance staticSpringApplication.exit(ApplicationContext, ExitCodeGenerator...) == pour le faire à votre place. Par exemple,

@SpringBootApplication
public class Example {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
        // ...determine it's time to stop...
        int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
            @Override
            public int getExitCode() {
                // no errors
                return 0;
            }
        });
        System.exit(exitCode);
    }
}
88

Dans une application de démarrage de printemps, vous pouvez utiliser quelque chose comme ça

ShutdownManager.Java

import org.springframework.context.ApplicationContext;
import org.springframework.boot.SpringApplication;

@Component
class ShutdownManager{

    @Autowired
    private ApplicationContext appContext;

    public void initiateShutdown(int returnCode){
        SpringApplication.exit(appContext, () -> returnCode);
    }
}
51
snovelli

Cela fonctionne, même fait est imprimé.

  SpringApplication.run(MyApplication.class, args).close();
  System.out.println("done");

Donc, en ajoutant .close() après run()

Explication:

public ConfigurableApplicationContext run(String... args)

Exécutez l'application Spring pour créer et actualiser un nouveau contexte d'application. Paramètres:

args - les arguments de l'application (généralement passés d'une Java)

Retourne: n ApplicationContext en cours d'exécution

et:

void close() Ferme ce contexte d'application en libérant toutes les ressources et tous les verrous que l'implémentation peut contenir. Cela inclut la destruction de tous les beans singleton en cache. Remarque: N'appelle pas la fermeture sur un contexte parent. les contextes parents ont leur propre cycle de vie indépendant.

Cette méthode peut être appelée plusieurs fois sans effets secondaires: Les appels ultérieurs ultérieurs dans un contexte déjà fermé seront ignorés.

Donc, fondamentalement, le contexte parent ne sera pas fermé, c’est pourquoi le VM ne s’arrête pas.

29
ACV

Dans l'application vous pouvez utiliser SpringApplication. Cela a une méthode statique exit() qui prend deux arguments: le ApplicationContext et un ExitCodeGenerator:

c'est-à-dire que vous pouvez déclarer cette méthode:

@Autowired
public void shutDown(ExecutorServiceExitCodeGenerator exitCodeGenerator) {
    SpringApplication.exit(applicationContext, exitCodeGenerator);
}

À l’intérieur des tests d’intégration vous pouvez y parvenir en ajoutant une annotation @DirtiesContext Au niveau de la classe:

  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) - Le contexte d'application associé sera marqué comme sale après la classe de test.
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - Le contexte d'application associé sera marqué comme sale après chaque méthode de test de la classe.

c'est à dire.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {Application.class},
    webEnvironment= SpringBootTest.WebEnvironment.DEFINED_PORT, properties = {"server.port:0"})
@DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_CLASS)
public class ApplicationIT {
...
2
magiccrafter

Cela garantira que l'application Spring Boot est correctement fermée et que les ressources sont libérées sur le système d'exploitation.

@Autowired
private ApplicationContext context;

@GetMapping("/shutdown-app")
public void shutdownApp() {

    int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
    System.exit(exitCode);
}
0
Samim