简体   繁体   中英

Scheduling: execute tasks only one time in spring boot

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM