手机扫码查看
2020java框架之Quartz作业调度框架
1.quartz使用
1.导入依赖
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.3</version> </dependency>
2.定义job
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//创建工作详情
JobDetail jobDetail = context.getJobDetail();
//获取工作的名称
String name = jobDetail.getKey().getName();
String group = jobDetail.getKey().getGroup();
String data = jobDetail.getJobDataMap().getString("data");
System.out.println("job执行,job名:"+name+",group:"+group+",Data:"+data+new Date());
}
}

3.测试
public class TestQuartz {
@Test
public void test1() throws SchedulerException, InterruptedException {
// 1. 创建Scheduler 调度器 核心组件
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 2. 定义Trigger 触发器 触发条件类 // 创建触发器 trigger
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("tigger1", "group1")//定义name,group
.startNow()//一旦加入scheduler 立即生效,即开始时间
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2)//每隔2秒执行一次
.withRepeatCount(1)).build();
// 3. 创建 JobDetail
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("job04", "group04")
.usingJobData("data", "hello world").build();
// 4. 注册 JobDetail 和 Trigger
scheduler.scheduleJob(jobDetail,trigger);
// 5. 启动调度器
scheduler.start();
// 6. 关闭调度器
Thread.sleep(4000);
scheduler.shutdown();
}
}

4.配置
# 指定调度器名称,非实现类 org.quartz.scheduler.instanceName = DefaultQuartzScheduler04 # 指定线程池实现类 org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool # 线程池线程数量 org.quartz.threadPool.threadCount = 15 # 优先级,默认5 org.quartz.threadPool.threadPriority = 5 # 非持久化job org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
2.Trigger(重点)
1.SimpleTrigger
指定从某一个时间开始,以一定的时间间隔(单位是毫秒)执行的任务。
它适合的任务类似于 9:00 开始 每隔1小时,执行一次。
属性有:
repeatForever() 重复间隔
withRepeatCount(int count) 重复次数
示例:
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2)//每隔2秒执行一次
.repeatForever()//永远执行).build();
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2)//每隔2秒执行一次
.withRepeatCount(1)//执行一次).build();
2.CalendarIntervalTrigger
类似于SimpleTrigger,指定从某一个时间开始,以一定的时间间隔(单位是毫秒)执行的任务。
但不同的是 SimpleTrigger 指定的时间间隔为毫秒,没办法指定每隔一个月执行一次(每月的时间间隔不是固定值),
而CalendarIntervalTrigger支持的间隔单位有秒,分钟,小时,天,月,年,周。
CalendarIntervalScheduleBuilder.calendarIntervalSchedule() .withIntervalInDays(2)//每2天执行一次 .withIntervalInWeeks(1)//每周执行一次
3.DailyTimeIntervalTrigger
指定每天的某个时间段内,以⼀定的时间间隔执⾏任务。并且它可以⽀持指定星期。
它适合的任务类似于:指定每天9:00 ⾄ 18:00 ,每隔70秒执⾏⼀次,并且只要周⼀⾄周五执⾏。
它的属性有:
startTimeOfDay 每天开始时间
endTimeOfDay 每天结束时间
daysOfWeek 需要执⾏的星期
interval 执⾏间隔
intervalUnit 执⾏间隔的单位(秒,分钟,⼩时,天,⽉,年,星期)
repeatCount 重复次数
DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule() .startingDailyAt(TimeOfDay.hourAndMinuteOfDay(9,0))//每天 9:00开始 .endingDailyAt(TimeOfDay.hourAndMinuteOfDay(18,0))//18:00结束 .onDaysOfTheWeek(DailyTimeIntervalScheduleBuilder.ALL_DAYS_OF_THE_WEEK)//每周的每一天 .onDaysOfTheWeek(DailyTimeIntervalScheduleBuilder.MONDAY_THROUGH_FRIDAY)//周一到周五 .onDaysOfTheWeek(DailyTimeIntervalScheduleBuilder.SATURDAY_AND_SUNDAY)//周六到周日
4.CronTrigger(重点)
适合于更复杂的任务,它⽀持类型于Linux Cron的语法(并且更强⼤)。基本上它覆盖了以上三个Trigger的绝⼤部分能⼒(但不是全部)——当然,也更难理解。
它适合的任务类似于:每天0:00,9:00,18:00各执⾏⼀次。
它的属性只有:
Cron表达式。但这个表示式本身就够复杂了
示例:
CronScheduleBuilder.cronSchedule("0 0/2 10-12 * * ?")//每天10:00-12:00,每个2分钟执行一次
).build();
CronScheduleBuilder.cronSchedule("0 30 9 ? * MON")//每周⼀,9:30执⾏⼀次
Cron表达式



3.JOB并发(重点)
job是有可能并发执⾏的,⽐如⼀个任务要执⾏10秒中,⽽调度算法是每秒中触发1次,那么就有可能多个任务被并发执⾏。
有时候我们并不想任务并发执⾏,⽐如这个任务要去”获得数据库中所有未发送邮件的名单“,如果是并发执⾏,就需要⼀个数据库锁去避免⼀个
数据被多次处理。这个时候⼀个@DisallowConcurrentExecution解决这个问题
示例:
@DisallowConcurrentExecution //会不允许并发执⾏,(如果每1s触发⼀次,但每个job要执⾏3秒)
public class MyJob implements Job{
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务调度:组:"+group+",⼯作名:"+name+" "+data+new Date());
}
}
4.spring整合quartz(重点)
1.依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
2.配置
调度器 SchedulerFactoryBean
触发器 CronTriggerFactoryBean
JobDetail JobDetailFactoryBean
点击链接:applicationContext_quartz.xml
3.代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext_quartz.xml")
public class TestSpringQuartz {
@Autowired
private StdScheduler stdScheduler;
@Test
public void test1() throws Exception {
System.out.println("hello world");
Thread.sleep(5000);
//删除 job
//暂停触发器的计时
/*stdScheduler.pauseTrigger(TriggerKey.triggerKey("hw_trigger","hw_trigger_group"));
//移除触发器中的任务
stdScheduler.unscheduleJob(TriggerKey.triggerKey("hw_trigger","hw_trigger_group"));
//移除 trigger 后,删除工作
stdScheduler.deleteJob(JobKey.jobKey("job1","group1"));*/
// job 暂停
/*stdScheduler.pauseJob(JobKey.jobKey("job1","group1"));
Thread.sleep(20000);
// job 恢复
stdScheduler.resumeJob(JobKey.jobKey("job1","group1"));*/
//暂停工作组内所有的job
GroupMatcher<JobKey> groups = GroupMatcher.groupEquals("group1");
stdScheduler.pauseJobs(groups);
Thread.sleep(5000);
stdScheduler.resumeJobs(groups);
}
}
5.持久化
建表:quartz官方的数据库表
点击链接直达:quartzSql.sql
配置:
jdbc.properties:
jdbc.user=root jdbc.password=root jdbc.url=jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf8 jdbc.driver=com.mysql.jdbc.Driver jdbc.maxPoolSize=3
点击链接直达:applicationContext_quartz2.xml
6.增加任务
实体类
@Data
public class JobAndTrigger {
private String jobName;
private String jobGroup;
private String jobClassName;
private String triggerName;
private String triggerGroup;
private BigInteger repeatInterval;
private BigInteger timesTriggered;
private String cronExpression;
private String timeZoneId;
}
控制层
@Controller
@RequestMapping("/quartz")
public class QuartzController {
@Autowired //注入了工厂中 调度器
private Scheduler scheduler;
@RequestMapping("/add")
public String addJob(JobAndTrigger jt) throws ClassNotFoundException, SchedulerException {
// 创建JobDetail
JobDetail jobDetail=null;
jobDetail = JobBuilder.newJob((Class<? extends Job>)Class.forName(jt.getJobClassName()))
.withIdentity(jt.getJobName(), jt.getJobGroup()).storeDurably(true).build();
CronTrigger cronTrigger = null;
cronTrigger = TriggerBuilder.newTrigger().withIdentity(jt.getJobName(),jt.getJobGroup())
.withSchedule(CronScheduleBuilder.cronSchedule(jt.getCronExpression()))
.build();
scheduler.scheduleJob(jobDetail,cronTrigger);
return "index";
}
}
页面
<form action="${pageContext.request.contextPath}/quartz/add" method="post">
jobName: <input type="text" name="jobName"> <br>
jobGroup: <input type="text" name="jobGroup"> <br>
cronExp: <input type="text" name="cronExpression"> <br>
jobClass: <input type="text" name="jobClassName"> <br>
<input type="submit" value="增加">
</form>
本文章资源github:点此直达



发表回复