您的位置 首页 java

springboot项目之定时任务框架Quartz

在web项目中,我们经常会遇到一些需要定时执行的任务,比如定时从某个服务器上下载文件、定时删除服务器上的某些文件、定时发送一些消息等等的操作,都需要定时任务。这里在springboot项目中使用到的一个定时任务的框架Quartz。这也是我在项目中使用到的定时任务框架,下面对该框架做一个简单的使用简介。

简而言之,Quartz是一种任务调度计划,它是由OpenSymphony提供的、开源的、java编写的强大任务调度框架。不管是小型项目,还是大型项目,集群项目,Quartz都可以完美地解决其中的任务调度计划问题。

springboot整合Quartz

首先在pom文件中添加Quartz的starter

 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
    <version>2.3.5.RELEASE</version>
</dependency>  

Quartz关键概念

Quartz主要有两个核心组件,一个是Job,另一个是Trigger。Job表示要执行的任务是什么,也就是要被调度的任务。Trigger表示什么时候触发该任务。在这里不去过多追究源码,我们先把框架用起来再说。那么在代码中怎么实现呢,下面我以一个定时下载的任务为例说明Quartz的使用。我们先创建两个核心组件的类,一个是关于Job的,一个是关于Trigger的。

创建任务 Job

我在项目下创建任务的包,在包下创建Job类。

创建Job

这里我创建EphDWJob类,用来定时从服务器上下载文件。

 package meicius.ori.quartzJobs;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class EphDWJob implements Job {
    Logger logger = LoggerFactory.getLogger(EphDWJob.class);
    String ephDownLoadUrlPrefix;
    /**
     * 要下载的文件名
     * **/    String ephFileName;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        this.executeMain();
    }

    public void executeMain(){
        try {
            FtpDownload.downLoadFtpFile(ephDownLoadUrlPrefix, 21, "anonymous", "");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}  

我们创建的Job要实现Quartz中Job接口,该接口中只有一个execute()方法,就是在这函数中执行我们的任务。

创建 Trigger

为了区分,我在项目下创建关于Trigger的包,在包下创建Trigger类。

创建Trigger

接下来在该包下创建Trigger类。在这里完成任务调度创建和启动任务调度。我在类的构造函数中完成任务调度的创建,把任务调度的创建和任务调度的启动分开。

 package meicius.ori.quartzScheduler;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service
public class EphDWScheduler {
    Logger logger = LoggerFactory.getLogger(EphDWScheduler.class);
    public SchedulerFactory schedulerFactory;
    public Scheduler scheduler;
    public JobDetail jobDetail;
    public CronTrigger cronTrigger;
    public TriggerKey triggerKey;
    public JobKey jobKey;

    /**
     * 在构造函数中创建调度器,加载任务
     * **/    public EphDWScheduler() throws SchedulerException {
        //1 创建调度器
        this.schedulerFactory = new StdSchedulerFactory();
        this.scheduler = schedulerFactory.getScheduler();

        //2 创建JobDetail实例,并与PrintWordsJob类绑定(Job执行的内容)
        this.jobDetail = JobBuilder.newJob(EphDWJob.class)
                .withIdentity("ephJobDetailDataDownLoadIdentity", "ephJobDetailDataDownLoadIdentityGroup1")
                .usingJobData("ephJobDetailDataDownLoadJobData", "ephJobDetailDataDownLoadValue")
                .build();

        //3 构建触发trigger实例 
        /**
         * corn 表达式
         * **/        this.cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity("ephTriggerDownLoadIdentity", "ephTriggerDownLoadIdentityGroup1")
                .usingJobData("ephTriggerDownLoadJobData","ephTriggerDownLoadDataValue")
                .withSchedule(CronScheduleBuilder.cronSchedule("0 15 */2 * * ?")) //每隔两个小时的第15分钟执行一次
                .build();

        this.triggerKey = TriggerKey.triggerKey("ephTriggerDownLoadIdentity", "ephTriggerDownLoadIdentityGroup1");
        this.jobKey = JobKey.jobKey("ephJobDetailDataDownLoadIdentity", "ephJobDetailDataDownLoadIdentityGroup1");
    }

    /**
     * 调度执行
     * **/    public String startJob(JobDetail jobDetail, CronTrigger cronTrigger) throws SchedulerException {
try{
            Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
            scheduler.start();
            return "下载任务启动成功";
        }catch (Exception e){
            return "下载任务启动失败" + e.getMessage();
        }
    }
}  

这里需要做的是

1)先创建任务调度器工厂schedulerFactory,然后再创建任务调度器scheduler。

2)创建任务详情JobDetail,将要被调度的任务添加进来。这里定义了在Quartz中任务所在的组名称和任务名称,供接下来调度使用。

3)创建trigger实例,也就是如何去调度,比如多久调度一次,什么时候开始调度等等。这里需要编写corn 表达式,就是用这个表达式来表明如何调度,Quartz提供了完美的表达式书写规则,可以满足任何的调度规则。这里写几个我用到的调度规则

 每个小时的第0,5,10,15,20,25,30,35,40,45,50,55分钟的第0秒执行
 (CronScheduleBuilder.cronSchedule("0 0,5,10,15,20,25,30,35,40,45,50,55 * * * ?"))
每10分钟执行一次
(CronScheduleBuilder.cronSchedule("* */10 * * * ?"))
每3秒钟执行一次
 (CronScheduleBuilder.cronSchedule("*/3 * * * * ?"))
每隔两个小时的第15分钟执行一次
(CronScheduleBuilder.cronSchedule("0 15 */2 * * ?"))  
每隔1分钟的第10秒钟执行一次
 (CronScheduleBuilder.cronSchedule("10 */1 * * * ?"))
每3秒钟执行一次
 (CronScheduleBuilder.cronSchedule("*/3 * * * * ?"))  

4)启动调度任务,根据任务所在组和任务名称

至此,就完成了一个Quartz的简单任务调度。

值得一说的是,在Quartz的Job中是无法注入Spring容器中的类的。这是因为Job是在Quartz框架中,Job实现类不接受Spring容器的管理。这里有两种方法解决此问题,一种是使用Quartz提供的JobFactory接口,就可以自定义实现创建Job的逻辑,并将jobFactory交给spring容器管理。另一种是直接从Spring容器中根据类或者类名查找要使用的类。我在项目中就使用的是第二种方法。

Spring容器中bean的获取

创建一个类,用来获取容器中的类。

 package meicius.ori.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextUtil.applicationContext = applicationContext;
    }
    public static ApplicationContext getApplicationContext(){
        return  applicationContext;
    }
    public static Object getBean(String beanName){
        return applicationContext.getBean(beanName);
    };
    //通过class获取Bean.
    public static <T> T getBeanByClass(Class<T> clazz){
        return applicationContext.getBean(clazz);
    }
}  

这样就可以完美地在Spring中使用Quartz了。

————

关注我,持续为您推荐在springboot项目中使用到的技术,遇到的问题。此外还会推荐前端Vue项目、分享整个前后端项目的搭建,完成过程中使用到的技术、遇到的问题。本项目要做一个卫星综合显示平台,后续会详细介绍本次项目,同时也会在git上分享,服务上线公网访问。

文章来源:智云一二三科技

文章标题:springboot项目之定时任务框架Quartz

文章地址:https://www.zhihuclub.com/179655.shtml

关于作者: 智云科技

热门文章

网站地图