Bir Spring Boot uygulamasını VM'yi sonlandırmadan programlı olarak nasıl kapatabilirim ?
Diğer çalışmalarda, tam tersi ne
new SpringApplication(Main.class).run(args);
Bir Spring Boot uygulamasını VM'yi sonlandırmadan programlı olarak nasıl kapatabilirim ?
Diğer çalışmalarda, tam tersi ne
new SpringApplication(Main.class).run(args);
Yanıtlar:
Birini kapatmak, SpringApplicationtemelde temelini kapatmak anlamına gelir ApplicationContext. SpringApplication#run(String...)Yöntem size bunu sağlıyor ApplicationContextbir şekilde ConfigurableApplicationContext. O close()zaman kendiniz yapabilirsiniz .
Örneğin,
@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();
}
}
Alternatif olarak, bunu sizin yerinize static SpringApplication.exit(ApplicationContext, ExitCodeGenerator...)yapmak için yardımcı yöntemi kullanabilirsiniz. Örneğin,
@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;
}
});
// or shortened to
// int exitCode = SpringApplication.exit(ctx, () -> 0);
System.exit(exitCode);
}
}
ExitCodeGeneratorkullanılabileceğini gösteriyor. mainNazikçe çıkmak için yöntemden dönebilirsiniz (çıkış kodu 0).
İlkbahar önyükleme uygulamasında bunun gibi bir şey kullanabilirsiniz
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);
}
}
ApplicationContextOtomatik olarak diğer çekirdeklere enjekte edilebileceğini göstermek için oy verin .
Bu işler, hatta yapılır basılmıştır.
SpringApplication.run(MyApplication.class, args).close();
System.out.println("done");
Yani .close()sonra eklemekrun()
Açıklama:
public ConfigurableApplicationContext run(String... args)Spring uygulamasını çalıştırın, yeni bir ApplicationContext oluşturun ve yenileyin. Parametreler:
args- uygulama argümanları (genellikle bir Java ana yönteminden geçirilir)Döndürür: çalışan bir ApplicationContext
ve:
void close()Uygulamanın tutabileceği tüm kaynakları ve kilitleri serbest bırakarak bu uygulama bağlamını kapatın. Bu, önbelleğe alınmış tüm tekil çekirdeklerinin yok edilmesini içerir. Not: Bir üst bağlamda close çağırmaz; üst bağlamların kendi bağımsız yaşam döngüleri vardır.Bu yöntem, yan etkiler olmaksızın birden çok kez çağrılabilir: Zaten kapalı bir bağlamda sonraki yakın çağrılar dikkate alınmaz.
Yani temelde, ana bağlamı kapatmayacak, bu yüzden VM kapanmıyor.
SpringApplication.exit(appContext, () -> returnCode).
SpringApplication.run(MyApplication.class, args), üst bağlam yoktur. Sadece bir bağlam vardır, bağlam yaratılır ve geri döner run, o zaman bunu hemen yaparsınız close. @Michael haklı. Bu, çoğu program olan Bahar bağlamı başlatıldıktan sonra herhangi bir şey yapması gereken programlar için çalışmayacaktır.
Uygulamada kullanabilirsiniz SpringApplication. Bu, exit()iki bağımsız değişken alan statik bir yönteme sahiptir: ApplicationContextve bir ExitCodeGenerator:
yani bu yöntemi beyan edebilirsiniz:
@Autowired
public void shutDown(ExecutorServiceExitCodeGenerator exitCodeGenerator) {
SpringApplication.exit(applicationContext, exitCodeGenerator);
}
Entegrasyon testlerinin içine@DirtiesContext , sınıf düzeyinde not ekleyerek bunu başarabilirsiniz :
@DirtiesContext(classMode=ClassMode.AFTER_CLASS) - İlişkili ApplicationContext, test sınıfından sonra kirli olarak işaretlenecektir.@DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - İlişkili ApplicationContext, sınıftaki her test yönteminden sonra kirli olarak işaretlenecektir.yani
@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 {
...
Bu, SpringBoot uygulamasının düzgün bir şekilde kapatılmasını ve kaynakların işletim sistemine geri verilmesini sağlayacaktır.
@Autowired
private ApplicationContext context;
@GetMapping("/shutdown-app")
public void shutdownApp() {
int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
System.exit(exitCode);
}