问题
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 ?
回答1:
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.
来源:https://stackoverflow.com/questions/37511097/scheduling-execute-tasks-only-one-time-in-spring-boot