在工作中不可避免会遇到任务调度的场景,无论是积分统计,生成报表,用户管理等都需要在某个时间节点进行相应的业务操作,而JDK中的Time和TimerTask适用场景偏向于持续时间短,简单重复的操作。因此针对时间跨度长,自定义时间触发的调度场景,更适合适用Quartz框架。以下便是Quartz的入门讲解以及使用:
Quartz基础结构:
1. Job:是一个只有voidexecute(JobExecutionContext context)方法的接口,开发者通过实现接口,在方法中定义需要完成的任务,context提供调度上下文的信息。
2. JobDetail:接收一个Job实现类,通过反射机制实例化Job。且每次执行Job,都会重新创建一个Job实例。因此这个类用于描述Job实现类和其他静态信息,以便实例化操作。
3. Trigger:代表触发Job执行的规则。主要有SimpleTrigger和CronTrigger两个子类。
4. Calendar:代表日期集合,可以与Trigger关联,以便在常规规则中取出某些特殊时间点。
5. Scheduler:Quartz的独立运行容器,JobDetail和Trigger注册到Scheduler内,以实现Trigger和Job的关联。Trigger和Jobdetai各自的名称和组名的组合是Scheduler的唯一标示,因此必须唯一(但是对于一个Trigger和一个Jobdetail,名称和组名不相关,因为在不同的集合内)一个Job可以对应多个Trigger而一个Trigger只能对应一个Job。
Job实例:
public class DealDataJob implements Job{
private static final Logger log = Logger.getLogger(DealDataJob.class);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
log.info("--------------");
log.info("预处理数据...");
RecordDao recordDao = new RecordDao();
recordDao.preDealData();
recordDao = null;
log.info(new Date());
log.info("处理数据结束");
log.info("--------------");
}
}
配置Scheduler:
public class QuartzManage {
private static final Logger log = Logger.getLogger(QuartzManage.class);
private static final String JOB_NAME = "deal_data";
private static final String GROUP_NAME = "group";
private static final String TRIGGER_NAME = "daily";
public static void manageJob() {
try {
JobDetail jobDetail = configJobDetail();
CronTrigger cronTrigger = configTrigger();
Scheduler scheduler = configScheduler(jobDetail, cronTrigger);
scheduler.start();
} catch (Exception e) {
e.printStackTrace();
log.info("manage failed");
log.error(e.getMessage());
}
}
/**
* 配置JobDetail
* @return
*/
private static JobDetail configJobDetail(){
JobDetailImpl jobDetail = new JobDetailImpl();
jobDetail.setName(JOB_NAME);
jobDetail.setGroup(GROUP_NAME);
jobDetail.setJobClass(DealDataJob.class);
return jobDetail;
}
/**
* 配置调度时间点Trigger
* @return
* @throws ParseException
*/
private static CronTrigger configTrigger() throws ParseException{
CronTriggerImpl cronTrigger = new CronTriggerImpl();
cronTrigger.setName(TRIGGER_NAME);
cronTrigger.setGroup(GROUP_NAME);
CronExpression expression = new CronExpression("0 0 6 * * ? *"); //每天早上六点触发操作
cronTrigger.setCronExpression(expression);
return cronTrigger;
}
/**
* 配置运行容器,并将工作和调度时间注册到运行容器中
* @param jobDetail
* @param trigger
* @return
* @throws SchedulerException
*/
private static Scheduler configScheduler(JobDetail jobDetail,Trigger trigger)
throws SchedulerException{
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.scheduleJob(jobDetail, trigger);
return scheduler;
}
public static void main(String[]args){
manageJob();
}
在Web应用中,只需要定义一个Listener,配置到web.xml中。调用Quartz即可完成任务调度:
public class ContextListener implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("context destroyed");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("context initialized");
QuartzManage.manageJob();
}
}
web.xml
<listener>
<listener-class>
com.bydota.product.listener.ContextListener
</listener-class>
</listener>