2014-04-08 17 views
54

Làm thế nào tôi có thể lập trình shutdown một Xuân Boot ứng dụng mà không chấm dứt VM?Lập trình đóng cửa mùa xuân Boot ứng dụng

Trong các công trình khác, trái ngược với

new SpringApplication(Main.class).run(args); 
+1

'SpringApplication' có một' 'static' phương pháp exit'. Xem javadoc. –

+0

Có, nhưng tôi cần tham chiếu đến ApplicationContext, SpringApplication không cung cấp. –

+1

'run' trả về nó. –

Trả lời

55

bế một SpringApplication là những gì cơ bản có nghĩa là đóng ApplicationContext cơ bản. Phương thức SpringApplication#run(String...) cung cấp cho bạn số ApplicationContext dưới dạng ConfigurableApplicationContext. Sau đó, bạn có thể tự mình close(). 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 phương pháp staticSpringApplication.exit(ApplicationContext, ExitCodeGenerator...) helper để 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; 
      } 
     }); 
     System.exit(exitCode); 
    } 
} 
+0

Câu hỏi: Bạn sẽ sử dụng ApplicationContext để làm gì? – lincolnadym

+0

@lincolnadym Để một 'ConfigurableApplicationContext'. Đó là kiểu trả về của 'run'. Tôi sẽ làm điều đó rõ ràng hơn trong câu trả lời. –

23

Tác phẩm này, thậm chí đã hoàn tất được in.

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

Vì vậy, thêm .close() sau run()

Giải thích:

public ConfigurableApplicationContext run(String... args)

Chạy ứng dụng Spring, tạo và làm mới một mới ApplicationContext. Tham số:

args - các đối số ứng dụng (thường là thông qua từ một chính phương thức Java )

Returns: một ApplicationContext chạy

và:

void close() Đóng này bối cảnh ứng dụng, giải phóng tất cả các tài nguyên và khóa mà việc triển khai có thể giữ. Điều này bao gồm phá hủy tất cả các hạt đơn được lưu trong bộ nhớ cache. Lưu ý: Không gọi gần trên bố cục của phụ huynh ; bối cảnh của cha mẹ có vòng đời độc lập của riêng họ.

Phương pháp này có thể được gọi nhiều lần mà không có tác dụng phụ: Các cuộc gọi gần sau trên ngữ cảnh đã bị đóng sẽ bị bỏ qua.

Về cơ bản, nó sẽ không đóng hoàn cảnh phụ huynh, đó là lý do VM không thoát.

+1

Điều này làm việc hoàn hảo với Spring Batch. – cahen

25

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; 

class ShutdownManager{ 

    @Autowired 
    private ApplicationContext appContext; 

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

Trong ứng dụng bạn có thể sử dụng SpringApplication. Này có exit() phương pháp tĩnh mà phải mất hai đối số: ApplicationContext và một ExitCodeGenerator:

tức là bạn có thể khai phương pháp này:

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

Bên trong các cuộc thử nghiệm 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 liên quan sẽ được đánh dấu là bẩn sau lớp kiểm tra.
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - ApplicationContext liên quan sẽ được đánh dấu là bẩn sau mỗi phương pháp thử nghiệm trong lớp.

ví dụ:

@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 { 
... 
Các vấn đề liên quan