调度:在spring boot中只执行一次任务 [英] Scheduling: execute tasks only one time in spring boot
问题描述
我正在尝试使用 Spring Boot 管理计划任务.我想在特定日期只执行一次(由用户指定).用户可以根据需要添加执行日期.这是我的工作:
@Component公共类 JobScheduler{@自动连线服务层服务;@PostConstruct公共无效executeJob(){尝试 {服务.执行();} 捕获(异常 e){//TODO 自动生成的 catch 块e.printStackTrace();}}}
这是执行方法:
私有TaskScheduler调度器;Runnable 示例Runnable = new Runnable(){@覆盖公共无效运行(){System.out.println("做点什么...");}};@覆盖@异步公共无效执行()抛出异常{尝试 {列表<日期>myListOfDates = getExecutionTime();//调用 dao 获取用户插入的日期ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();scheduler = new ConcurrentTaskScheduler(localExecutor);for(日期 d : myListOfDates ){scheduler.schedule(exampleRunnable, d);}} 捕获(异常 e){//TODO 自动生成的 catch 块e.printStackTrace();}}
问题 1:我使用 PostConstruct 注释.因此,当调用 executeJob 方法时,List 'myListOfDates' 中没有日期.
问题 2:假设 myListOfDates 包含日期,如果用户输入另一个日期,我如何获取最新日期?
问题 3:如果我使用 @Scheduled(initailDelay=10000, fixedRate=20000) 而不是 @PostConstruct 注释,它将解决第一个问题,但它会例如每 20 秒执行一次我的工作.
有什么线索吗?
从你的问题中我可以推断出,你问的是如何根据春季开始的日期列表触发作业.
首先,而不是在 bean/组件中使用 @PostConstruct
,我认为最好将它挂钩到应用程序级别的事件侦听器中.请参阅 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/event/ContextRefreshedEvent.html
这样,您可以确保所有 bean 都已初始化,因此您可以加载 myListOfDates
,然后启动调度程序.
第二,就像我在评论中所说的那样,我建议您改用现有的第 3 方库.我只在 java 中使用过 Quartz,所以我将使用 Quartz 进行说明.
第三,我猜您将 myListOfDates
存储在某种数据库(不是内存)中,因此用户可以修改预定日期.如果你按照我的建议使用 3rd-party 库,Quartz 有使用 JDBC 的 JobStore 参见 http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-09.html#TutorialLesson9-JDBCJobStore
老实说,我从不使用那个,但我相信该库具有根据数据库中保存的内容触发作业的机制.这可能就是您要找的.p>
Im trying to manage scheduled tasks using spring boot. I want to execute my job only one time at a particular date ( specified by the user ). User can add dates for execution as much as he wants.Here is my Job :
@Component
public class JobScheduler{
@Autowired
ServiceLayer service;
@PostConstruct
public void executeJob(){
try {
service.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And here is the execute method :
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();
}
}
Issue 1 : Im using PostConstruct annotation. Thus, when executeJob method is called, there is no dates in the List 'myListOfDates'.
Issue 2 : Supposing that myListOfDates contains dates, how can i get the latest dates in case user entered another one?
Issue 3 : If i use @Scheduled(initailDelay=10000, fixedRate=20000) instead of @PostConstruct annotation, it will resolve the first issue, but it will execute my job every 20s for instance.
Any clue ?
From what I can infer from your question is, you are asking how to make jobs triggered based on some list of date when spring started.
First, instead of using @PostConstruct
in a bean/component, I think it's better to hook it into application level event listener instead. See http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/event/ContextRefreshedEvent.html
That way,you can make sure you all beans initialized, hence you can load myListOfDates
, and then start the scheduler.
Second, like what I said in my comment, I would suggest you to uses existing 3rd-party library instead. I only ever uses Quartz in java, so I will ilustrate using Quartz.
Third, I guess you are storing myListOfDates
in some kind of database (not memory), hence the ability of user to modify the scheduled dates. If you follow my suggestion in using 3rd-party library, Quartz have JobStore using JDBC See http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-09.html#TutorialLesson9-JDBCJobStore
Honestly I never uses that one, but I believe the library have mechanism to trigger the job based on what saved in the database. This might be what you are looking for.
这篇关于调度:在spring boot中只执行一次任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!