2014-10-12 17 views
14

Tôi đang xây dựng một ứng dụng java Dòng lệnh bằng cách sử dụng Spring Boot để làm cho nó hoạt động nhanh chóng.Cách tắt ứng dụng dòng lệnh Khởi động Spring

Ứng dụng tải các loại tệp khác nhau (ví dụ CSV) và tải chúng vào Cơ sở dữ liệu Cassandra. Nó KHÔNG sử dụng bất kỳ thành phần web nào, nó không phải là một ứng dụng web.

Sự cố tôi đang gặp phải là dừng ứng dụng khi hoàn thành công việc. Tôi đang sử dụng giao diện Spring CommandLineRunner với một @Component để chạy các tác vụ, như được hiển thị bên dưới, nhưng khi công việc được hoàn thành, ứng dụng không dừng lại, nó vẫn tiếp tục chạy vì một lý do nào đó và tôi không thể tìm cách ngăn chặn nó.

@Component 
public class OneTimeRunner implements CommandLineRunner { 

    @Autowired 
    private CassandraOperations cassandra; 

    @Autowired 
    private ConfigurableApplicationContext context; 

    @Override 
    public void run(String... args) throws Exception { 
     // do some work here and then quit 
     context.close(); 
    } 
} 

CẬP NHẬT: vấn đề có vẻ là spring-cassandra, vì không có gì khác trong dự án là. Có ai biết tại sao nó giữ các chủ đề chạy trong nền mà ngăn chặn các ứng dụng từ dừng lại?

CẬP NHẬT: sự cố đã biến mất bằng cách cập nhật lên phiên bản khởi động mùa xuân mới nhất.

+0

Bất kỳ giải pháp nào cho điều này? Nó xảy ra với khởi động bình thường mùa xuân (không có cassandra) – ACV

+1

@ACV không, tôi chỉ sống với nó. Tôi đã học được rằng một số mô-đun mùa xuân sinh ra các chủ đề của riêng chúng, ví dụ: Cassandra có một hồ bơi thread cho các kết nối, hoặc RabbitMQ khi bạn sử dụng các container listener. Chúng mất một thời gian để tắt sau khi bạn gọi 'context.close()' để dừng ứng dụng. – ESala

+0

Xem câu trả lời của tôi bên dưới – ACV

Trả lời

8

Câu trả lời tùy thuộc vào những gì nó vẫn đang hoạt động. Bạn có thể có thể tìm ra với một bãi chứa thread (ví dụ như sử dụng jstack). Nhưng nếu nó là bất cứ điều gì đã được bắt đầu bởi mùa xuân, bạn sẽ có thể sử dụng ConfigurableApplicationContext.close() để dừng ứng dụng trong phương thức main() của bạn (hoặc trong CommandLineRunner).

+0

Ok, tôi đã gỡ lỗi ứng dụng bằng điểm ngắt và có 17: Chủ đề [Nhân viên I/O mới # (1-17)].Tôi sẽ phải điều tra về điều đó. Về ConfigurableApplicationContext.close(), nó mất khoảng 30 giây để dừng ứng dụng, đó có phải là bình thường không ?? – ESala

+0

Nó sẽ phải chờ đợi cho bất cứ điều gì đang làm việc để phát hành các chủ đề. Âm thanh như một thời gian chờ với tôi. –

+0

Chính xác, tôi nghi ngờ Spring Cassandra đang giữ những luồng này chạy vì một lý do nào đó. – ESala

9

Tôi đã tìm được giải pháp. Bạn có thể sử dụng điều này:

public static void main(String[] args) { 
    SpringApplication.run(RsscollectorApplication.class, args).close(); 
    System.out.println("done"); 
} 

Chỉ cần sử dụng .đóng khi chạy.

+0

well yeah .... nếu bạn nhìn vào mã trên câu hỏi, tôi đang làm điều đó. 'SpringApplication.run (Main.class, args)' trả về một 'ConfigurableApplicationContext' mà bạn có thể lưu trữ hoặc' @ Autowire' sau này như tôi làm. Vấn đề tôi gặp phải trong câu hỏi này là sau khi gọi 'close()' trong ngữ cảnh, các quầy ứng dụng trong một thời gian. – ESala

+0

OK, rõ ràng. Có thể là các tệp cần thời gian để được đưa vào cơ sở dữ liệu – ACV

4

Tôi cũng gặp vấn đề này trong dự án hiện tại của tôi (ứng dụng khởi động mùa xuân). Giải pháp của tôi là:

// releasing all resources 
((ConfigurableApplicationContext) ctx).close(); 
// Close application 
System.exit(0); 

context.close() đừng dừng ứng dụng bảng điều khiển của chúng tôi, nó chỉ giải phóng tài nguyên.

0

Sử dụng org.springframework.boot.SpringApplication#exit. Ví dụ.

@Component 
public class OneTimeRunner implements CommandLineRunner { 

    @Autowired 
    private ConfigurableApplicationContext context; 

    @Override 
    public void run(String... args) throws Exception { 
     SpringApplication.exit(context); 
    } 
} 
1

Đây là sự kết hợp của @EliuX câu trả lời với @Quan Vo một. Cảm ơn cả hai người!

Điều khác biệt chính là tôi chuyển mã phản hồi SpringApplication.exit (context) như một tham số cho System.exit() vì vậy nếu có lỗi khi đóng ngữ cảnh Spring bạn sẽ thấy.

SpringApplication.exit() sẽ đóng ngữ cảnh mùa xuân.

System.exit() sẽ đóng ứng dụng.

@Component 
public class OneTimeRunner implements CommandLineRunner { 

    @Autowired 
    private ConfigurableApplicationContext context; 

    @Override 
    public void run(String... args) throws Exception { 
     System.exit(SpringApplication.exit(context)); 
    } 
} 
Các vấn đề liên quan