2015-05-20 14 views
17

Có thể lên lịch phương thức dịch vụ Spring chỉ một lần vào đúng thời gian đã chỉ định không? Ví dụ: thời gian hiện tại là 2 giờ chiều nhưng khi tôi nhấn nút tác vụ, tôi muốn phương thức dịch vụ của tôi bắt đầu lúc 8 giờ tối. Tôi quen thuộc với chú thích @Scheduled và tôi không chắc chắn cách viết biểu thức cron không chạy định kỳ. Hình ảnh này @Scheduled(cron = "0 0 20 * * ?") kích hoạt mỗi ngày lúc 8 giờ tối.
Bất kỳ đề xuất nào?Tác vụ lập lịch trình mùa xuân - chỉ chạy một lần

+0

u có thể sử dụng lịch trình thạch anh :) –

Trả lời

16

Bạn có thể sử dụng một trong các triển khai TaskScheduler của Spring. Tôi đã cung cấp một ví dụ bên dưới với một ví dụ không yêu cầu cấu hình quá nhiều (ConcurrentTaskScheduler bao bọc một trình thực thi được lập lịch trình đơn luồng).

Phương pháp đơn giản nhất là một trong những tên lịch mà phải mất một Runnable và ngày mà thôi. Điều đó sẽ khiến nhiệm vụ chạy một lần sau khi thời gian được chỉ định. Tất cả các phương thức khác đều có khả năng lập lịch các tác vụ để chạy lặp lại.

Tìm hiểu thêm về task execution & scheduling

Ví dụ đơn giản làm việc:

private TaskScheduler scheduler; 

Runnable exampleRunnable = new Runnable(){ 
    @Override 
    public void run() { 
     System.out.println("Works"); 
    } 
}; 

@Async 
public void executeTaskT() { 
    ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor(); 
    scheduler = new ConcurrentTaskScheduler(localExecutor); 

    scheduler.schedule(exampleRunnable, 
      new Date(1432152000000L));//today at 8 pm UTC - replace it with any timestamp in miliseconds to text 
} 

... 

executeTaskT() //call it somewhere after the spring application has been configured 

Note:

Để kích hoạt hỗ trợ cho @Scheduled và @Async chú thích thêm @EnableScheduling và @EnableAsync với một trong các @Configurationcủa bạnlớp


Cập nhật - hủy nhiệm vụ theo lịch trình

phương pháp lịch TaskScheduler trả về một ScheduledFuture mà là một hành động trì hoãn kết quả mang có thể được hủy bỏ.

Vì vậy, để hủy bỏ nó, bạn cần phải giữ một xử lý cho nhiệm vụ theo lịch trình (tức là giữ đối tượng trả về ScheduledFuture).

Thay đổi mã trên cho hủy nhiệm vụ:

  1. Khai báo ScheduledFuture bên ngoài phương pháp executeTaskT của bạn. private ScheduledFuture scheduledFuture;

  2. Sửa gọi để lấy hẹn để giữ các đối tượng trở lại như vậy: scheduledFuture = scheduler.schedule(exampleRunnable, new Date(1432152000000L));

  3. Gọi hủy trên đối tượng scheduledFuture nơi nào đó trong mã của bạn boolean mayInterruptIfRunning = true; scheduledFuture.cancel(mayInterruptIfRunning);

+0

Tác phẩm này. Tôi đã mở rộng bản ConcurrentTaskScheduler với trình quản lý tác vụ quản lý luồng máy chủ như thế này 'scheduler = new ConcurrentTaskScheduler (workManagerTaskExecutor, Executors.newSingleThreadScheduledExecutor())'. Nó là một loại 'org.springframework.scheduling.commonj.WorkManagerTaskExecutor' và được cung cấp bởi máy chủ JNDI đăng ký. – shx

+1

Tuyệt vời, đã làm việc cho tôi. btw, nếu runnable với các tham số là cần thiết, bạn có thể viết một phương thức chấp nhận tham số và trả về Runnable và sau đó vượt qua phương thức này trong scheduler với tham số scheduler.schedule (createRunnable (param1), new Date (1432152000000L)); –

+1

Có phải @Async bắt buộc phải đạt được nó không? – Angom

0

Để không tạo ScheduledExecutorServiceConcurrentTaskScheduler ở mọi phương thức gọi là thuận tiện để khởi tạo TaskScheduler khi tạo dịch vụ, ví dụ:

private final TaskScheduler taskScheduler = 
       new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(10)); 

@Async không có nghĩa là chúng tôi chỉ lên lịch công việc và thoát khỏi phương pháp.

Các vấn đề liên quan