调度:在 spring 启动时只执行一次任务
Scheduling: execute tasks only one time in spring boot
我正在尝试使用 spring 引导管理计划任务。我想在特定日期(由用户指定)只执行一次我的工作。用户可以添加执行日期,因为他 wants.Here 是我的工作:
@Component
public class JobScheduler{
@Autowired
ServiceLayer service;
@PostConstruct
public void executeJob(){
try {
service.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这是执行方法:
private TaskScheduler scheduler;
Runnable exampleRunnable = new Runnable(){
@Override
public void run() {
System.out.println("do something ...");
}
};
@Override
@Async
public void execute() throws Exception {
try {
List<Date> myListOfDates = getExecutionTime(); // call dao to get dates insered by the user
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
scheduler = new ConcurrentTaskScheduler(localExecutor);
for(Date d : myListOfDates ){
scheduler.schedule(exampleRunnable, d);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
问题 1:我正在使用 PostConstruct 注释。因此,当调用 executeJob 方法时,List 'myListOfDates'.
中没有日期
问题 2:假设 myListOfDates 包含日期,如果用户输入另一个日期,我如何获取最新日期?
问题 3:如果我使用 @Scheduled(initailDelay=10000, fixedRate=20000) 而不是 @PostConstruct 注释,它将解决第一个问题,但它会每 20 秒执行一次我的作业。
有线索吗?
根据你的问题我可以推断,你问的是如何根据 spring 开始的日期列表来触发作业。
First,而不是在 bean/component 中使用 @PostConstruct
,我认为最好将其挂接到应用程序级事件侦听器中。参见 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/event/ContextRefreshedEvent.html
这样,您可以确保所有 bean 都已初始化,因此您可以加载 myListOfDates
,然后启动调度程序。
其次,就像我在评论中所说的那样,我建议您改用现有的第 3 方库。我只在 java 中使用过 Quartz,因此我将使用 Quartz 进行说明。
Third,我猜你是将 myListOfDates
存储在某种数据库(不是内存)中,因此用户可以修改预定日期。如果你按照我的建议使用 3rd-party 库,Quartz 有 JobStore 使用 JDBC See http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-09.html#TutorialLesson9-JDBCJobStore
老实说我从来没有用过那个,但我相信图书馆有机制根据数据库中保存的内容触发作业。这可能就是您要找的。
我正在尝试使用 spring 引导管理计划任务。我想在特定日期(由用户指定)只执行一次我的工作。用户可以添加执行日期,因为他 wants.Here 是我的工作:
@Component
public class JobScheduler{
@Autowired
ServiceLayer service;
@PostConstruct
public void executeJob(){
try {
service.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这是执行方法:
private TaskScheduler scheduler;
Runnable exampleRunnable = new Runnable(){
@Override
public void run() {
System.out.println("do something ...");
}
};
@Override
@Async
public void execute() throws Exception {
try {
List<Date> myListOfDates = getExecutionTime(); // call dao to get dates insered by the user
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
scheduler = new ConcurrentTaskScheduler(localExecutor);
for(Date d : myListOfDates ){
scheduler.schedule(exampleRunnable, d);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
问题 1:我正在使用 PostConstruct 注释。因此,当调用 executeJob 方法时,List 'myListOfDates'.
中没有日期问题 2:假设 myListOfDates 包含日期,如果用户输入另一个日期,我如何获取最新日期?
问题 3:如果我使用 @Scheduled(initailDelay=10000, fixedRate=20000) 而不是 @PostConstruct 注释,它将解决第一个问题,但它会每 20 秒执行一次我的作业。
有线索吗?
根据你的问题我可以推断,你问的是如何根据 spring 开始的日期列表来触发作业。
First,而不是在 bean/component 中使用 @PostConstruct
,我认为最好将其挂接到应用程序级事件侦听器中。参见 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/event/ContextRefreshedEvent.html
这样,您可以确保所有 bean 都已初始化,因此您可以加载 myListOfDates
,然后启动调度程序。
其次,就像我在评论中所说的那样,我建议您改用现有的第 3 方库。我只在 java 中使用过 Quartz,因此我将使用 Quartz 进行说明。
Third,我猜你是将 myListOfDates
存储在某种数据库(不是内存)中,因此用户可以修改预定日期。如果你按照我的建议使用 3rd-party 库,Quartz 有 JobStore 使用 JDBC See http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-09.html#TutorialLesson9-JDBCJobStore
老实说我从来没有用过那个,但我相信图书馆有机制根据数据库中保存的内容触发作业。这可能就是您要找的。