Java&Quartz实现任务调度
Java&Quartz实现任务调度
1.Quartz的作用
定时自动执行任务
2.预备
相关包官方网站
quartz2.2.1
quartz-jobs2.2.1
POM文件
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
3.Quartz核心
3.1.Job接口
被调度的任务,只有一个方法execute(JobExecutionContext xontext),Job运行时的信息保存在JobDataMap中
3.2.JobDetail类
实现Job接口,用来描述Job的相关信息,包含Name,Group,JobDataMap等
3.3 JobExecutionContext类
定时程序执行的run-time的上下文环境,用于得到Job的名字、配置的参数等
3.3 JobDataMap类
用来描述一个作业的参数,参数可以为金和基本类型或者某个对象的引用
3.3 JobListener接口
监听作业状态
3.3 TriggaerListener接口
监听触发器状态
3.3 JobStore
3.3.Tigger抽象类
触发器,描述执行Job的触发规则,有SimpleTrigger和CronTrigger两个子类
3.3.1.SimpleTrigger类
继承自Trigger类,每隔xx毫秒/秒执行一次,主要实现固定一次或者固定时间周期类任务的触发
3.3.2.CronTrigger类
继承自Trigger类,使用Cron表达式,实现各种复杂时间规则调度方案,如每天的某个时间,或每周的某几天触发执行之类
3.4.Calendar包
一些日历特定时间点的集合,包内包含以下几个类
3.4.1 BaseCalendar类
3.4.2 AnnualCalendar类
排除每一年中指定的一天或者多天
3.4.3 CalendarComparator类
3.4.4 CronCalendar类
使用表达式排除某时间段不执行
3.4.5 DailyCalendar类
指定的时间范围内每天不执行
3.4.6 HolidayCalendar类
排除节假日
3.4.7 MonthlyCalendar类
配出月份中的数天
3.4.8 WeeklyCalendar类
排除没周中的一天或者多天
3.5.Scheduler类
任务调度器,代表一个Quartz独立容器。
Scheduler可以将JobDetail和Trigger绑定,当Trigger触发时,对应的Job就会被执行,Job和Trigger是1:n(一对多)的关系
3.6Misfire类
错误的任务,本该执行单没有执行的任务调度
4.实现
1.单任务实现
1.定义一个任务,新建任务类继承自Job类
package com;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class DemoJob implements Job {
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println(new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
}
2.新建类执行这个任务(SimpleTrigger)
package com;
import java.util.Date;
import org.quartz.DateBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class QuartzDemo {
public void simpleRun() throws SchedulerException {
// 创建一个调度器工厂
SchedulerFactory factory = new StdSchedulerFactory();
//任务执行时间
//Date runTime = DateBuilder.evenMinuteDate(new Date());
Date runTime = DateBuilder.evenSecondDateAfterNow();
// 新建JobDetail对象并绑定一个任务
JobDetail jobDetail = JobBuilder.newJob(DemoJob.class)
.withIdentity("demo_job", "demo_group")
.build();
// 定义调度规则
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("demo_trigger", "demo_group")
//.startNow()//立即执行
.startAt(new Date())//设置触发开始的时间
.withSchedule(
SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(1)//时间间隔
.withRepeatCount(5)//重复次数(n+1),比如这里将执行6次
).build();//生成触发器
// 从工厂获取一个调度器对象
Scheduler scheduler = factory.getScheduler();
//绑定触发器和任务
scheduler.scheduleJob(jobDetail,trigger);
System.out.println(jobDetail.getKey() + " 运行在: " + runTime);
scheduler.start();
}
public static void main(String[] args) {
QuartzDemo demo = new QuartzDemo();
try {
demo.simpleRun();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
2.多任务实现
- 测试任务类
新建两个DemoJonOne和DemoJobTwo,都实现Job接口,内容如下
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println(new SimpleDateFormat("HH:mm:ss").format(new Date())+" Runed "+getClass().getName());
}
2.新建QuartzUtil类,内容如下
package com;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class QuartzUtil {
private final static String JOB_GROUP_NAME = "QUARTZ_JOBGROUP_NAME";// 任务组
private final static String TRIGGER_GROUP_NAME = "QUARTZ_TRIGGERGROUP_NAME";// 触发器组
/**
* 添加任务的方法
*
* @param jobName 任务名
* @param triggerName 触发器名
* @param jobClass 执行任务的类
* @param seconds 间隔时间
* @throws SchedulerException
*/
public static void addJob(String jobName, String triggerName, Class<? extends Job> jobClass, int seconds)
throws SchedulerException {
// 创建一个SchedulerFactory工厂实例
SchedulerFactory sf = new StdSchedulerFactory();
// 通过SchedulerFactory构建Scheduler对象
Scheduler sche = sf.getScheduler();
// 用于描述Job实现类及其他的一些静态信息,构建一个作业实例
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, JOB_GROUP_NAME).build();
// 构建一个触发器,规定触发的规则
Trigger trigger = TriggerBuilder.newTrigger()// 创建一个新的TriggerBuilder来规范一个触发器
.withIdentity(triggerName, TRIGGER_GROUP_NAME)// 给触发器起一个名字和组名
.startNow()// 立即执行
.withSchedule(
SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(seconds)// 时间间隔 // 单位:秒
.repeatForever()// 一直执行
).build();// 产生触发器
//绑定触发器和任务
sche.scheduleJob(jobDetail, trigger);
// 启动
sche.start();
}
public static void main(String[] args) {
try {
// 添加第一个任务 每隔10秒执行一次
QuartzUtil.addJob("job1", "trigger1", DemoJobOne.class, 2);
// 添加第二个任务 每隔20秒执行一次
QuartzUtil.addJob("Job2", "trigger2", DemoJobTwo.class, 5);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
以上方法属于手动调用,如果是web项目中就不同了
添加POM
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
package servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.quartz.SchedulerException;
import com.DemoJobOne;
import com.DemoJobTwo;
import com.QuartzUtil;
public class InitServlet extends HttpServlet {
private static final long serialVersionUID = 8507188690597926975L;
/**
* 因为我们不需要处理请求与响应的消息操作,所以这个地方只留一个初始化的操作就行了,用以执行任务调度的入口
*/
public void init() throws ServletException {
try {
// 添加第一个任务 每隔2秒执行一次
QuartzUtil.addJob("job1", "trigger1", DemoJobOne.class, 2);
// 添加第二个任务 每隔5秒执行一次
QuartzUtil.addJob("Job2", "trigger2", DemoJobTwo.class, 5);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
2.注册servlet
<servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>servlet.InitServlet</servlet-class>
<!-- 设置优先级 -->
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>InitServlet</servlet-name>
<url-pattern>/InitServlet</url-pattern>
</servlet-mapping>
3.复杂规则任务调度(CronTrigger)
在每分钟的1-30秒执行示例
package com;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class CronTriggerDemo {
public static void main(String[] args) throws SchedulerException {
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
JobDetail job = JobBuilder
.newJob(DemoJobOne.class)
.withIdentity("job","group")
.build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("trigger", "group")
.startNow().withSchedule(
CronScheduleBuilder
.cronSchedule("1-30 * * * * ?")
).build();
scheduler.scheduleJob(job,trigger);
scheduler.start();
}
}
5.Cron表达式
规则
格式
s M h d m w [y]
s:seconds,取值0-59,允许- * /;
M:minutes,取值0-59,允许- * /;
h:hour,取值0-23,允许- * /;
d:day of month,取值1-31,允许- * ? / L W;
m:month,取值1-12/JAN-DEC,允许- * /;
w:day of week,取值1-7/SUN-SAT,允许- * ? / L #;
y:year,可选,取值empty、1970-2099,允许- * /;
符号解释
、 指定枚举值,如在秒字段使用10、12,则表示只有第10秒和第12秒执行
- 指定区间范围,配合使用,如在小时字段使用10-12,表示在10、11、12时都会触发
* 代表所有值,单独使用,如在秒字段使用,表示每秒触发
? 代表不确定值,单独使用,不用关心的值
/ 用于递增触发,配合使用,n/m,从n开始,每次增加m,如在秒字段设置5/15,表示从第5秒开始,每15秒触发一次
L 表示最后,单独使用,如在秒字段使用,代表第59秒触发,如果在前面加上数字,则表示该数据的最后一个,如在周字段使用6L,则表示本月最后一个周五
W 表示最近的工作日,不会跨月,比如30W,30号是周六,则不会顺延至下周一来执行,如在月字段使用15W,则表示到本月15日最近的工作日(周一到周五)
# 用来指定x的第n个工作日,如在周字段使用6#3则表示该月的第三个星期五
月取值
一月:JAN/0
二月:FEB/1
三月:MAR/2
四月:APR/3
五月:MAY/4
六月:JUN/5
七月:JUL/6
八月:AUG/7
九月:SEP/8
十月:OCT/9
十一月:NOV/10
十二月:DEC/11
周取值
周日:SUN/1
周一:MON/2
周二:TUE/3
周三:WED/4
周四:THU/5
周五:FRI/6
周六:SAT/7
示例
0/20 * * * * ? 每20秒执行一次
1-30 * * * * ? 在1-30秒执行
15 0/2 * * * ? 偶数分钟的第15秒执行
0 0/2 8-17 * * ? 从8时到17时 ,每个偶数分钟执行一次
0 0/3 17-23 * * ? 从17时到23时,每3分钟运行一次
0 0 10am 1,15 * ? 每个月的1号和15号的上午10点 运行
0,30 * * ? * MON-FRI 周一至周五,每30秒运行一次
0,30 * * ? * SAT,SUN 周六、周日,每30秒运行一次
0 0 12 * * ? 每天12点触发
0 15 10 ? * * 每天10点15分触发
0 15 10 * * ? 每天10点15分触发
0 15 10 * * ? * 每天10点15分触发
0 15 10 * * ? 2005 2005年每天10点15分触发
0 * 14 * * ? 每天下午的 2点到2点59分每分触发
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
0 0/5 14,18 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发) 每天下午的 18点到18点59分(整点开始,每隔5分触发)
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
0 15 10 15 * ? 每月15号上午10点15分触发
0 15 10 L * ? 每月最后一天的10点15分触发
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)
6.Spring整合Quartz
需要Spring-context-support包支持,POM如下
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
新建两种Job测试类-->DemoSimpleJob类和DemoCronJob类,并继承自QuartzJobBean,代码如下
package com;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class DemoJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
System.out.println(new SimpleDateFormat("hh:mm:ss").format(new Date()) + " 输出自:" + getClass().getName());
}
}
配置spring bean如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!--org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean -->
<!-- 配置任务 -->
<bean id="demoCronJob"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.DemoCronJob" />
</bean>
<bean id="demoSimpleJob"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.DemoSimpleJob" />
</bean>
<!-- <property name="jobDataAsMap"> -->
<!-- 配置触发器 -->
<bean id="simpleTrigger"
class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="demoSimpleJob" />
<property name="startDelay" value="1000" />
<property name="repeatInterval" value="2000" />
</bean>
<bean id="cornTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="demoCronJob" />
<property name="cronExpression" value="1-30 * * * * ?" />
</bean>
<!-- 配置调度器 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cornTrigger" />
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
启动
package com;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
}
有待补充
Java&Quartz实现任务调度的更多相关文章
- java Quartz任务调度器
1.quarz对java1.5实现的简单调度做了封装 /** * quartz对任务调度进了高度抽象: 1调度器:2任务:3触发器 * Job接口(任务):定义需要调度的任务 ...
- Spring Quartz实现任务调度
任务调度 在企业级应用中,经常会制定一些"计划任务",即在某个时间点做某件事情 核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作 任务调度涉及多线程并发.线程池维 ...
- java Quartz定时器任务与Spring task定时的几种实现,
java Quartz定时器任务与Spring task定时的几种实现 基于java 的定时任务实现, Quartz 时间详细配置 请查阅 http://www.cnblogs.com/si ...
- 项目ITP(五) spring4.0 整合 Quartz 实现任务调度
前言 系列文章:[传送门] 项目需求: 二维码推送到一体机上,给学生签到扫描用.然后需要的是 上课前20分钟 ,幸好在帮带我的学长做 p2p 的时候,接触过.自然 quartz 是首选.所以我就配置了 ...
- 项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送邮件 5.基于poi实现分区导出
1 Shiro整合ehCache缓存授权信息 当需要进行权限校验时候:四种方式url拦截.注解.页面标签.代码级别,当需要验证权限会调用realm中的授权方法 Shiro框架内部整合好缓存管理器, ...
- 聊Java中的任务调度的实现方法及比较
前言 任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务.本文由浅入深介绍四种任务调度的 Java 实现: Timer ScheduledExecutor 开源工具包 Quartz ...
- Quartz实现任务调度
一.任务调度概述 在企业级应用中,经常会制定一些"计划任务",即在某个时间点做某件事情,核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作,任务调度涉及多线程并发. ...
- quartz.net任务调度:源码及使用文档
目录: 1.quartz.net任务调度:源码及使用文档 2.quartz.net插件类库封装 前言 前段时间把自己封装quartz.net 类库的过程总结到博客园,有网友想要看一下源码,所以就把源码 ...
- linux 下部署 java quartz job
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
随机推荐
- [python3]未配置locale的主机出现UnicodeDecodeError: 'ascii' codec can't decode byte 0x....的解决
之前写的发邮件的程序部署到vps的时候出现了 UnicodeDecodeError: 'ascii' codec can't decode byte 0x.... 的错误. 按理说UnicodeDec ...
- logo的普遍写法
h1为了搜索引擎优化<div class="logo"> <h1> <a href="#">XX</a> < ...
- 51Nod 1600 Simple KMP 解题报告
51Nod 1600 Simple KMP 对于一个字符串\(|S|\),我们定义\(fail[i]\),表示最大的\(x\)使得\(S[1..x]=S[i-x+1..i]\),满足\((x<i ...
- Shell基本正则表达式和扩展正则表达式
BRE和ERE的区别 基本正则表达式(BRE)和扩展正则表达式(ERE)的区别仅仅是元字符(meta charactor)的区别而已. BRE: 只有^$.*[]是元字符 ERE: ^$.[]*+() ...
- 制作linux根文件系统
转载地址:http://wenku.baidu.com/view/2cb1b4707fd5360cba1adb14.html 2011十一月 24 转 嵌入式根文件系统制作 (3985) (0) 转自 ...
- 本地JAR包打入本地mvn仓库
新建目录my-lib,将jar包移动到目录中,添加pom文件(用alipay测试) <project xmlns="http://maven.apache.org/POM/4.0.0& ...
- JAVA学习之环境搭建
了解到JAVA语言的跨平台性的原理是通过在不同的操作系统中安装对应版本的的JAVA虚拟机(JVM)实现 开发JAVA前必须先搭建JAVA环境: 1.JAVA开发工具包JDK(JAVA DEVELOPM ...
- Retrofit全攻略——进阶篇
最近事比较多,距离上次写文章已经过去了一个月了.上一篇文章Retrofit全攻略——基础篇 介绍了Retrofit的基础用法,这篇文章介绍点进阶的用法. 打印网络日志 在开发阶段,为了方便调试,我们需 ...
- 剑指offer第二版面试题1:数组中重复的数字(JAVA版)
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复的次数.请找出数组中任意一个重复的数字.例如如果输入长度为7的数组{ ...
- Codeforces 1176B - Merge it!
题目链接:http://codeforces.com/problemset/problem/1176/B 题意:给定序列,任意俩个元素可以相加成一个元素,求序列元素能被3整除的最大数量. 思路: 对于 ...