Quartz是一个功能丰富的开源作业调度库,可以集成到几乎任何Java应用程序中
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.3version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plusartifactId>
<version>2.1.2version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatisplus-spring-boot-starterartifactId>
<version>1.0.4version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
dependency>
<dependency>
<groupId>org.quartz-schedulergroupId>
<artifactId>quartzartifactId>
<version>2.2.1version>
dependency>
定时任务通用接口
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public interface BaseJob extends Job{
@Override
public void execute(JobExecutionContext context) throws JobExecutionException;
}
定时任务接口的实现类
import com.quartz.springquartz.task.BaseJob;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import java.time.LocalDateTime;
public class TestJob implements BaseJob {
public TestJob() {
}
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobKey key = jobDetail.getKey();
System.out.println(key.getName()+"-"+key.getGroup()+"执行时间: " + LocalDateTime.now().toString());
}
}
quartz的JAVA config bean注入
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import javax.sql.DataSource;
import org.quartz.*;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class QuartzConfig {
@Bean(name="SchedulerFactory")
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setQuartzProperties(quartzProperties());
return factory;
}
/*
* quartz初始化监听器
*/
@Bean
public QuartzInitializerListener executorListener() {
return new QuartzInitializerListener();
}
/*
* 通过SchedulerFactoryBean获取Scheduler的实例
*/
@Bean(name="Scheduler")
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}
/**
* 设置quartz属性,可以从properties配置中读取
*/
public Properties quartzProperties() throws IOException {
Properties prop = new Properties();
prop.put("quartz.scheduler.instanceName", "ServerScheduler");
prop.put("org.quartz.scheduler.instanceId", "AUTO");
prop.put("org.quartz.scheduler.skipUpdateCheck", "true");
prop.put("org.quartz.scheduler.instanceId", "NON_CLUSTERED");
prop.put("org.quartz.scheduler.jobFactory.class", "org.quartz.simpl.SimpleJobFactory");
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
prop.put("org.quartz.threadPool.threadCount", "5");
return prop;
}
}
操作定时任务的service类,就不写接口了直接实现,数据库dao和service自己实现,Task是我定义的pojo
import com.quartz.springquartz.entity.Task;
import com.quartz.springquartz.manager.TaskService;
import com.quartz.springquartz.task.BaseJob;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class ScheduleJobService {
@Autowired @Qualifier("Scheduler")
private Scheduler scheduler;
//自己选择所用的dao
@Autowired
TaskService taskService;
public String addJob(Task task) throws Exception{
// 启动调度器
scheduler.start();
//构建job信息
JobDetail jobDetail = JobBuilder
.newJob(getClass(task.getClassName()).getClass()).withIdentity(task.getName(), task.getGroup()).build();
//表达式调度构建器(即任务执行的时间)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCron());
//按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getName(), task.getGroup())
.withSchedule(scheduleBuilder).build();
try {
scheduler.scheduleJob(jobDetail, trigger);
//taskService.insert(task);
} catch (SchedulerException e) {
e.printStackTrace();
}
return "success";
}
public JobDetail jobPause(String jobName, String jobGroupName) throws Exception
{
scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
JobDetail detail = scheduler.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
return detail;
}
public void jobreschedule(String jobName, String jobGroupName, String cronExpression) throws Exception
{
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
} catch (SchedulerException e) {
System.out.println("更新定时任务失败"+e);
}
}
public static BaseJob getClass(String classname) throws Exception
{
Class> class1 = Class.forName(classname);
return (BaseJob)class1.newInstance();
}
}
添加监听器,应用启动时,从数据库中读取定时任务并加入
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.quartz.springquartz.entity.Task;
import com.quartz.springquartz.manager.TaskService;
import com.quartz.springquartz.service.ScheduleJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import java.util.List;
@Configuration
public class JobListener implements ApplicationListener<ContextRefreshedEvent>{
@Autowired
TaskService taskService;
@Autowired
ScheduleJobService scheduleJobService;
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent){
EntityWrapper ew = new EntityWrapper<>();
ew.where("status = {0}",1);
List tasks = taskService.selectList(ew);
System.out.println("task size = "+tasks.size());
try {
for (Task task : tasks) {
scheduleJobService.addJob(task);
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
再写一个controller测试用,就可以玩去了
import com.quartz.springquartz.entity.Task;
import com.quartz.springquartz.service.ScheduleJobService;
import com.quartz.springquartz.task.BaseJob;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping(value="/job")
public class TestController {
//加入Qulifier注解,通过名称注入bean
@Autowired @Qualifier("Scheduler")
private Scheduler scheduler;
@Autowired
ScheduleJobService scheduleJobService;
@RequestMapping("/add")
public String addJob(@RequestBody Task task) throws Exception{
scheduleJobService.addJob(task);
return "success";
}
@PostMapping(value="/pause")
public JobKey pausejob(@RequestBody Map map) throws Exception
{
JobDetail detail = scheduleJobService.jobPause((String)map.get("jobName"), (String)map.get("jobGroupName"));
return detail.getKey();
}
@PostMapping(value="/edit")
public String rescheduleJob(@RequestBody Map map) throws Exception
{
scheduleJobService.jobreschedule((String)map.get("jobName"),(String)map.get("jobGroupName"),(String)map.get("cronExpression"));
return "success";
}
}
最初入门,quartz配置中的存储,分布式应用暂时没看,下篇文章再说,只实现了单机中定时任务的数据库持久化和动态添加