Bagaimana saya bisa pemrograman penutupan sebuah musim semi Boot aplikasi tanpa mengakhiri VM ?
Dalam karya lain, kebalikan dari
new SpringApplication(Main.class).run(args);
Bagaimana saya bisa pemrograman penutupan sebuah musim semi Boot aplikasi tanpa mengakhiri VM ?
Dalam karya lain, kebalikan dari
new SpringApplication(Main.class).run(args);
Jawaban:
Menutup SpringApplicationpada dasarnya berarti menutup yang mendasarinya ApplicationContext. The SpringApplication#run(String...)metode memberikan Anda bahwa ApplicationContextsebagai ConfigurableApplicationContext. Anda kemudian bisa close()melakukannya sendiri.
Sebagai contoh,
@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();
}
}
Alternatifnya, Anda dapat menggunakan static SpringApplication.exit(ApplicationContext, ExitCodeGenerator...)metode helper untuk melakukannya untuk Anda. Sebagai contoh,
@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);
}
}
ExitCodeGeneratorbisa digunakan. Anda bisa kembali dari mainmetode untuk keluar dengan anggun (kode keluar 0).
Dalam aplikasi boot musim semi Anda dapat menggunakan sesuatu seperti ini
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);
}
}
ApplicationContextkaleng disuntikkan secara otomatis ke kacang lain.
Ini bekerja, bahkan selesai dicetak.
SpringApplication.run(MyApplication.class, args).close();
System.out.println("done");
Jadi menambahkan .close()setelahrun()
Penjelasan:
public ConfigurableApplicationContext run(String... args)Jalankan aplikasi Spring, buat dan refresh ApplicationContext baru. Parameter:
args- argumen aplikasi (biasanya diteruskan dari metode utama Java)Mengembalikan: ApplicationContext yang sedang berjalan
dan:
void close()Tutup konteks aplikasi ini, lepaskan semua sumber daya dan kunci yang mungkin dimiliki implementasi. Ini termasuk menghancurkan semua kacang tunggal yang di-cache. Catatan: Tidak memanggil dekat pada konteks induk; konteks induk memiliki siklus hidupnya sendiri-sendiri.Metode ini bisa dipanggil berkali-kali tanpa efek samping: Penutupan panggilan berikutnya pada konteks yang sudah tertutup akan diabaikan.
Jadi pada dasarnya, ini tidak akan menutup konteks induk, itulah mengapa VM tidak berhenti.
SpringApplication.exit(appContext, () -> returnCode).
SpringApplication.run(MyApplication.class, args), maka tidak ada konteks induk. Hanya ada satu konteks, konteks dibuat dan dikembalikan run, yang kemudian Anda segera close. @Michael benar. Ini tidak akan berfungsi untuk program yang perlu melakukan apa pun setelah konteks Spring diinisialisasi, yang merupakan sebagian besar program.
Dalam aplikasi, Anda dapat menggunakan SpringApplication. Ini memiliki exit()metode statis yang mengambil dua argumen: the ApplicationContextdan an ExitCodeGenerator:
yaitu Anda dapat mendeklarasikan metode ini:
@Autowired
public void shutDown(ExecutorServiceExitCodeGenerator exitCodeGenerator) {
SpringApplication.exit(applicationContext, exitCodeGenerator);
}
Di dalam tes Integrasi Anda dapat melakukannya dengan menambahkan @DirtiesContextanotasi di tingkat kelas:
@DirtiesContext(classMode=ClassMode.AFTER_CLASS) - ApplicationContext terkait akan ditandai sebagai kotor setelah kelas pengujian.@DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - ApplicationContext terkait akan ditandai sebagai kotor setelah setiap metode pengujian di kelas.yaitu
@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 {
...
Ini akan memastikan bahwa aplikasi SpringBoot ditutup dengan benar dan sumber daya dilepaskan kembali ke sistem operasi,
@Autowired
private ApplicationContext context;
@GetMapping("/shutdown-app")
public void shutdownApp() {
int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
System.exit(exitCode);
}