无框架定时任务quartz

一、quartz的基本组成

1、调度器--------------Scheduler
    Scheduler被用来对Trigger和Job进行管理。Trigger和JobDetail可以注册到Scheduler中,两者在Scheduler中都拥有自己的唯一的组和名称用来进行彼此的区分,Scheduler可以通过组名或者名称来对Trigger和JobDetail来进行管理。一个Trigger只能对应一个Job,但是一个Job可以对应多个Trigger。每个Scheduler都包含一个SchedulerContext,用来保存Scheduler的上下文。Job和Trigger都可以获取SchedulerContext中的信息。
  2、触发器--------------Trigger
    Trigger是用来定义Job的执行规则,主要有四种触发器,其中SimpleTrigger和CronTrigger触发器用的最多。
      SimpleTrigger:从某一个时间开始,以一定的时间间隔来执行任务。它主要有两个属性,repeatInterval 重复的时间间隔;repeatCount 重复的次数,实际上执行的次数是n+1,因为在startTime的时候会执行一次。
      CronTrigger:适合于复杂的任务,使用cron表达式来定义执行规则。
      CalendarIntervalTrigger:类似于SimpleTrigger,指定从某一个时间开始,以一定的时间间隔执行的任务。 但是CalendarIntervalTrigger执行任务的时间间隔比SimpleTrigger要丰富,它支持的间隔单位有秒,分钟,小时,天,月,年,星期。相较于SimpleTrigger有两个优势:1、更方便,比如每隔1小时执行,你不用自己去计算1小时等于多少毫秒。 2、支持不是固定长度的间隔,比如间隔为月和年。但劣势是精度只能到秒。它的主要两个属性,interval 执行间隔;intervalUnit 执行间隔的单位(秒,分钟,小时,天,月,年,星期)
      DailyTimeIntervalTrigger:指定每天的某个时间段内,以一定的时间间隔执行任务。并且它可以支持指定星期。它适合的任务类似于:指定每天9:00 至 18:00 ,每隔70秒执行一次,并且只要周一至周五执行。它的属性有startTimeOfDay 每天开始时间;endTimeOfDay 每天结束时间;daysOfWeek 需要执行的星期;interval 执行间隔;intervalUnit 执行间隔的单位(秒,分钟,小时,天,月,年,星期);repeatCount 重复次数
    所有的trigger都包含了StartTime和endTIme这两个属性,用来指定Trigger被触发的时间区间。

3、任务-----------------Job

Job是一个任务接口,开发者定义自己的任务须实现该接口实现void execute(JobExecutionContext context)方法,JobExecutionContext中提供了调度上下文的各种信息。Job中的任务有可能并发执行,例如任务的执行时间过长,而每次触发的时间间隔太短,则会导致任务会被并发执行。如果是并发执行,就需要一个数据库锁去避免一个数据被多次处理。可以在execute()方法上添加注解@DisallowConcurrentExecution解决这个问题。

4、任务详情-----------JobDetail
    Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail承担了这一角色。所以说JobDetail是任务的定义,而Job是任务的执行逻辑。
  6、JobDataMap
    用来保存JobDetail运行时的信息,JobDataMap的使用:.usingJobData(“name”,“kyle”)或者.getJobDataMap(“name”,“kyle”)
  7、cron表达式
    Cron表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感
    星号():可用在所有字段中,表示对应时间域的每一个时刻,例如, 在分钟字段时,表示“每分钟”;
    问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于点位符;
    减号(-):表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12;
    逗号(,):表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五;
    斜杠(/):x/y表达一个等步长序列,x为起始值,y为增量步长值。如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y;
    L:该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L在日期字段中,表示这个月份的最后一天,如一月的31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示“这个月的最后X天”,例如,6L表示该月的最后星期五;
    W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。W字符串只能指定单一日期,而不能指定日期范围;
    LW组合:在日期字段可以组合使用LW,它的意思是当月的最后一个工作日;
井号(#):该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发;
    C:该字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。
二、简单应用代码如下
配置schedule.xml

<?xml version="1.0" encoding="UTF-8"?> D:\model\2\ 2 EData * */3 * * * ? 1 创建测试类 public static void main(String[] args) { System.out.println("Server Starting ..."); long startTime = System.currentTimeMillis(); //文件存储地址 String eDataPath; String subno; try { //quartz配置 //创建schedule Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); //读取任务配置文件 System.out.println("loading config ..."); SXmlHelper xml = SConstConfig.getConfig("schedule.xml"); eDataPath = xml.getValue("config.service.path"); subno = xml.getValue("config.service.subno"); Element tasks = xml.getElement("config.tasks"); Iterator it = tasks.elements().iterator(); while(it.hasNext()) { Element task = (Element)it.next(); String group = task.element("group").getText(); //获取定时 String cron = task.element("cron").getText(); Element keys = task.element("keys"); Iterator itKeys = keys.elements().iterator(); while(itKeys.hasNext()) { Element keyEl = (Element)itKeys.next(); String key = keyEl.getText(); //生成Trigger CronTrigger trigger = newTrigger() .withIdentity("trigger_" + key, "group_" + group) .withSchedule(cronSchedule(cron)) .build(); //定义JobDetail JobDetail job = newJob(JobFactory.getJobType(key)) .withIdentity("job_"+key, "group_"+group) .usingJobData("eDataPath", eDataPath) .usingJobData("subno", subno) .build(); //加入调度 scheduler.scheduleJob(job, trigger);
			}
		}
		//启动调度
		scheduler.start();
		long endTime = System.currentTimeMillis();
	}catch(Exception e) {
		SLog.error(e);
	}
}
加载JobFactory根据传入的key,选择执行的任务
public class JobFactory {
public static Class<? extends Job> getJobType(String key) throws ClassNotFoundException {
	switch (key) {
	case  "1":
		return 1.class;//告警历史数据
	default:
		throw new ClassNotFoundException("can not find the job class related to the key:" + key);
	}
}

}
1class类要继承job
public class 1 implements Job {

@Override
public void execute(JobExecutionContext context) throws JobExecutionException{
	JobDataMap dataMap = context.getJobDetail().getJobDataMap();
	ServiceUtil serviceUtil = new ServiceUtil(context);
//书写业务逻辑
//例如:
		System.out.println("hello quartz");
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值