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 SpringApplication
pada dasarnya berarti menutup yang mendasarinya ApplicationContext
. The SpringApplication#run(String...)
metode memberikan Anda bahwa ApplicationContext
sebagai 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);
}
}
ExitCodeGenerator
bisa digunakan. Anda bisa kembali dari main
metode 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);
}
}
ApplicationContext
kaleng 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 ApplicationContext
dan 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 @DirtiesContext
anotasi 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);
}