Làm thế nào tôi có thể lập trình tắt máy một mùa xuân Boot ứng dụng mà không chấm dứt VM ?
Trong các tác phẩm khác, điều ngược lại với
new SpringApplication(Main.class).run(args);
Làm thế nào tôi có thể lập trình tắt máy một mùa xuân Boot ứng dụng mà không chấm dứt VM ?
Trong các tác phẩm khác, điều ngược lại với
new SpringApplication(Main.class).run(args);
Câu trả lời:
Đóng một SpringApplication
cơ bản có nghĩa là đóng cơ bản ApplicationContext
. Các SpringApplication#run(String...)
phương pháp mang đến cho bạn mà ApplicationContext
như một ConfigurableApplicationContext
. Sau đó bạn có thể close()
tự mình.
Ví dụ,
@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();
}
}
Ngoài ra, bạn có thể sử dụng static
SpringApplication.exit(ApplicationContext, ExitCodeGenerator...)
phương pháp trợ giúp để làm điều đó cho bạn. Ví dụ,
@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
có thể được sử dụng. Bạn chỉ có thể quay lại từ main
phương thức để thoát một cách duyên dáng (thoát mã 0).
Trong một ứng dụng khởi động mùa xuân, bạn có thể sử dụng một cái gì đó như thế này
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
có thể tự động tiêm vào hạt đậu khác.
Điều này làm việc, thậm chí được thực hiện được in.
SpringApplication.run(MyApplication.class, args).close();
System.out.println("done");
Vì vậy, thêm .close()
saurun()
Giải trình:
public ConfigurableApplicationContext run(String... args)
Chạy ứng dụng Spring, tạo và làm mới một ApplicationContext mới. Thông số:
args
- các đối số ứng dụng (thường được truyền từ một phương thức chính của Java)Trả về: một ApplicationContext đang chạy
và:
void close()
Đóng ngữ cảnh ứng dụng này, giải phóng tất cả tài nguyên và khóa mà việc triển khai có thể giữ lại. Điều này bao gồm việc phá hủy tất cả các hạt singleton được lưu trong bộ nhớ cache. Lưu ý: Không gọi đóng trên ngữ cảnh mẹ; ngữ cảnh mẹ có vòng đời riêng, độc lập.Phương thức này có thể được gọi nhiều lần mà không có tác dụng phụ: Các lệnh gọi đóng tiếp theo trên ngữ cảnh đã đóng sẽ bị bỏ qua.
Vì vậy, về cơ bản, nó sẽ không đóng ngữ cảnh gốc, đó là lý do tại sao VM không thoát.
SpringApplication.exit(appContext, () -> returnCode)
.
SpringApplication.run(MyApplication.class, args)
, thì không có ngữ cảnh gốc. Chỉ có một ngữ cảnh duy nhất, bối cảnh được tạo và trả lại bởi run
bạn, sau đó bạn ngay lập tức close
. @Michael nói đúng. Điều này sẽ không hoạt động đối với các chương trình cần thực hiện bất kỳ điều gì sau khi ngữ cảnh Spring được khởi tạo, đây là hầu hết các chương trình.
Trong ứng dụng bạn có thể sử dụng SpringApplication
. Phương thức này có một exit()
phương thức tĩnh nhận hai đối số: the ApplicationContext
và an ExitCodeGenerator
:
tức là bạn có thể khai báo phương thức này:
@Autowired
public void shutDown(ExecutorServiceExitCodeGenerator exitCodeGenerator) {
SpringApplication.exit(applicationContext, exitCodeGenerator);
}
Trong các bài kiểm tra Tích hợp, bạn có thể đạt được nó bằng cách thêm @DirtiesContext
chú thích ở cấp lớp:
@DirtiesContext(classMode=ClassMode.AFTER_CLASS)
- ApplicationContext được liên kết sẽ bị đánh dấu là bẩn sau lớp thử nghiệm.@DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)
- ApplicationContext được liên kết sẽ bị đánh dấu là bẩn sau mỗi phương thức kiểm tra trong lớp.I E
@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 {
...
Điều này sẽ đảm bảo rằng ứng dụng SpringBoot được đóng đúng cách và các tài nguyên được giải phóng trở lại hệ điều hành,
@Autowired
private ApplicationContext context;
@GetMapping("/shutdown-app")
public void shutdownApp() {
int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
System.exit(exitCode);
}