调度:在spring boot中只执行一次任务 [英] Scheduling: execute tasks only one time in spring boot

查看:469
本文介绍了调度:在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

老实说,我从不使用那个,但我相信该库具有根据数据库中保存的内容触发作业的机制.这可能就是您要找的.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆