springboot整合Quartz实现定时任务
Quartz 核心概念
- Job 表示一个工作,要执行的具体内容。此接口中只有一个方法,如下:void execute(JobExecutionContext context)
- JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
- Trigger 代表一个调度参数的配置,什么时候去调。
- Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了
实现一个简单的定时自动生成任务的步骤如下:
1.在pom文件中添加依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency><!-- 该依赖必加,里面有sping对schedule的支持 -->
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
2。编写一个任务调度类
import static org.quartz.JobBuilder.newJob;
/**
* @author wuhan
* quartz定时执行任务---定时自动生成巡视任务
*
*/
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Configuration
@Component
public class QuartzTest implements ApplicationRunner{
@Autowired
private Environment env;
public void startScheduler() {
try {
//创建scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger").startNow()
// .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(120)
// .repeatForever()).build();
//定义一个CronTrigger
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("cronTrigger")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 3 ? * *")).build();
//定义一个JobDetail
JobDetail job = newJob(TaskQuartz.class) //定义Job类为TaskQuartz类,这是真正的执行逻辑所在
.withIdentity("job1", "group1") //定义name/group
.usingJobData("name", "quartz") //定义属性
.build();
//加入这个调度
scheduler.scheduleJob(job, cronTrigger);
//启动之
scheduler.start();
//运行一段时间后关闭
// Thread.sleep(60000);
// scheduler.shutdown(true);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run(ApplicationArguments args) throws Exception {
//只有在配置文件中root.runner=true的时候才触发
if(env.getProperty("root.runner").matches("true")) {
this.startScheduler();
}
}
}
3.编写生成定时任务的具体任务内容
import java.util.Date;
import javax.annotation.PostConstruct;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.taijue.boot.gas.patrol.task.Service.QuartzService;
@Component
public class TaskQuartz implements Job {
public static TaskQuartz taskQuartz;
@Autowired
QuartzService quartzService;
// 初始化
@PostConstruct
public void init() {
taskQuartz = this;
taskQuartz.quartzService = this.quartzService;
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//我这里只是调用了createPatrolTask方法(createPatrolTask里面写了任务生成的具体内容)
taskQuartz.quartzService.createPatrolTask();
System.err.println(new Date()+"后台自动生成了巡视任务");
}
}
4.定时任务生成的具体内容,也就是第三步中的createPatrolTask方法,这里面是我自己的项目的定时任务的内容
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.taijue.boot.gas.patrol.path.domain.Path;
import com.taijue.boot.gas.patrol.path.domain.PathPoint;
import com.taijue.boot.gas.patrol.path.service.PathPointService;
import com.taijue.boot.gas.patrol.path.service.PathService;
import com.taijue.boot.gas.patrol.task.TaskQuartz;
import com.taijue.boot.gas.patrol.task.domain.PatrolPoint;
import com.taijue.boot.gas.patrol.task.domain.PatrolTask;
/**
* @author wuhan
*
*/
@Service
public class QuartzService {
@Autowired
PathService pathService;
@Autowired
PatrolTaskService patrolTaskService;
@Autowired
PathPointService pathPointService;
@Autowired
PatrolPointService patrolPointService;
public static QuartzService quartzService;
//初始化 必须要有,不然自动注入后还是没用
@PostConstruct
public void init() {
quartzService = this;
quartzService.pathService = this.pathService;
quartzService.patrolTaskService=this.patrolTaskService;
quartzService.pathPointService=this.pathPointService;
quartzService.patrolPointService=this.patrolPointService;
}
//创建巡视任务
public void createPatrolTask() {
List<Path> pathList =quartzService.pathService.getPath();
if(pathList.size()>0) {
for(int i=0;i<pathList.size();i++) {
createPatrolTask(pathList.get(i));
}
}
}
public void createPatrolTask(Path path){
PatrolTask patrolTask=new PatrolTask();
patrolTask.setName(path.getName());
patrolTask.setTarget("计划");
patrolTask.setPathid(path.getId());
patrolTask.setPathname(path.getName());
patrolTask.setDeptcode(path.getDeptcode());
patrolTask.setDeptname(path.getDeptname());
patrolTask.setReceiveid(path.getOprtid());
patrolTask.setReceivename(path.getOprtname());
Date date=new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
patrolTask.setAssigntime(sdf.parse(sdf.format(date)));
} catch (ParseException e) {
e.printStackTrace();
}
patrolTask.setFlag(1);
quartzService.patrolTaskService.save(patrolTask);
quartzService.createPatrolPoint(path.getId(), patrolTask.getId());
}
public void createPatrolPoint(Long pathid,Long taskid) {
List<PathPoint> list=quartzService.pathPointService.findByPathid(pathid);
if(list.size()>0) {
for(int i=0;i<list.size();i++) {
PathPoint pathPoint=list.get(i);
PatrolPoint patrolPoint = new PatrolPoint();
patrolPoint.setTaskid(taskid);
patrolPoint.setPoint(pathPoint);
patrolPoint.setX(pathPoint.getX());
patrolPoint.setY(pathPoint.getY());
quartzService.patrolPointService.save(patrolPoint);
}
}
}
}
cronExpression表达式:
- “*”字符被用来指定所有的值。如:”*“在分钟的字段域里表示“每分钟”。
- “-”字符被用来指定一个范围。如:“10-12”在小时域意味着“10点、11点、12点”。
- “,”字符被用来指定另外的值。如:“MON,WED,FRI”在星期域里表示”星期一、星期三、星期五”。
- “?”字符只在日期域和星期域中使用。它被用来指定“非明确的值”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。看下面的例子你就会明白
- “L”字符指定在月或者星期中的某天(最后一天)。即“Last ”的缩写。但是在星期和月中“L”表示不同的意思,如:在月子段中“L”指月份的最后一天-1月31日,2月28日,如果在星期字段中则简单的表示为“7”或者“SAT”。如果在星期字段中在某个value值得后面,则表示“某月的最后一个星期value”,如“6L”表示某月的最后一个星期五。
- “W”字符只能用在月份字段中,该字段指定了离指定日期最近的那个星期日。
- “#”字符只能用在星期字段,该字段指定了第几个星期value在某月中。
每一个元素都可以显式地规定一个值(如6),一个区间(如9-12),一个列表(如9,11,13)或一个通配符(如*)。“月份中的日期”和“星期中的日期”这两个元素是互斥的,因此应该通过设置一个问号(?)来表明你不想设置的那个字段。
这样,简单的在指定时间生成定时任务的功能就完成了 ,当然在实际项目中一般会把任务调度的参数配置存放在数据库或者配置文件中,你可以参照https://www.cnblogs.com/tinyj/p/9798456.html