刚完成了一个使用quartz调度的功能,因为是在老项目上添加,jdk1.6,所以只能使用quartz1.x 来进行实现,quartz1.x 和quartz2.x代码还是有区别的,很多quartz1.x 的方法都被淘汰了,但是还是记录一下备忘。
一. 环境
jdk1.6
quartz-1.6.0.jar
spring2.x + struts2 + hibernate ,使用的xml,未使用注解
二. 调度并在job中注入service
实现调度其实很简单,quartz有现成的demo,但是还需在job中注入service,这个稍微有点麻烦。
1. 代码结构
2. 调度
如果只实现单纯的调度任务,只需要定义作业(如DzfpJob.java)和触发器(CronTriggerRunner.java)即可
2.1 引入jar包
我这是老项目,直接将quartz-1.6.0.jar 包放入lib下
2.2 定义作业job
直接实现Job接口即可,代码如下:
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
@SuppressWarnings("all")
public class DzfpJob implements Job {
private Logger logger = Logger.getLogger(this.getClass().getName());
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
@Override
public void execute(JobExecutionContext jobContext)
throws JobExecutionException {
System.out.println("调度任务开始: " + format.format(new Date()));
}
}
触发器 CronTriggerRunner.java,这个代码直接从官方实例中拿的,没做改动:
import org.quartz.CronExpression;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
/**
*/
public class CronTriggerRunner {
public void task() throws SchedulerException {
// Initiate a Schedule Factory
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
// Retrieve a scheduler from schedule factory
Scheduler scheduler = schedulerFactory.getScheduler();
// current time
long ctime = System.currentTimeMillis();
// Initiate JobDetail with job name, job group, and executable job class
JobDetail jobDetail = new JobDetail("jobDetail", "jobDetailGroup",
DzfpJob.class); //这是我们刚刚定义的DzfpJob
// Initiate CronTrigger with its name and group name
CronTrigger cronTrigger = new CronTrigger("cronTrigger", "triggerGroup");
try {
// setup CronExpression
/**
* 测试(每5秒执行一次): "0/5 * * * * ?"
*/
CronExpression cexp = new CronExpression(
"0/5 * * * * ?");
// Assign the CronExpression to CronTrigger
cronTrigger.setCronExpression(cexp);
} catch (Exception e) {
e.printStackTrace();
}
// schedule a job with JobDetail and Trigger
scheduler.scheduleJob(jobDetail, cronTrigger);
// start the scheduler
scheduler.start();
}
public static void main(String args[]) {
try {
CronTriggerRunner qRunner = new CronTriggerRunner();
qRunner.task();
} catch (Exception e) {
e.printStackTrace();
}
}
}
到这,一个调度实例就完成了,直接运行主方法类,效果如下:
因为我的项目是在tomcat中启动,需要启动tomcat时同时启动调度,所以需要配置监听,实现ServletContextListener接口,InitLoadTask.java代码如下:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.quartz.SchedulerException;
public class InitLoadTask implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
CronTriggerRunner qRunner = new CronTriggerRunner();
try {
qRunner.task();
} catch (SchedulerException e) {
// TODO Auto-generated catch block
System.out.println("调度任务启动失败....");
e.printStackTrace();
}
}
}
然后在web.xml 定义:
<listener>
<listener-class>com.nuonuodzfp.quartz.InitLoadTask</listener-class>
</listener>
这样,启动tomcat后,调度就开始了。
3.在job中注入service
3.1 继承 QuartzInitializerListener类
QuartzServletContextListener.java代码如下:
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import org.quartz.SchedulerException;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.quartz.impl.StdSchedulerFactory;
public class QuartzServletContextListener extends QuartzInitializerListener {
public static final String MY_CONTEXT_NAME = "servletContext";
@Override
public void contextDestroyed(ServletContextEvent sce) {
super.contextDestroyed(sce);
}
@Override
public void contextInitialized(ServletContextEvent sce) {
super.contextInitialized(sce);
ServletContext servletContext = sce.getServletContext();
StdSchedulerFactory factory = (StdSchedulerFactory) servletContext
.getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY);
try {
factory.getScheduler().getContext().put(
QuartzServletContextListener.MY_CONTEXT_NAME,
servletContext);
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.2 web.xml中增加监听
<listener>
<listener-class>com.nuonuodzfp.quartz.QuartzServletContextListener</listener-class>
</listener>
3.3 job中获取
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletContext;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;
import com.bdxc.service.sf_util.UtilService;
import com.nuonuodzfp.quartz.QuartzServletContextListener;
@SuppressWarnings("all")
public class DzfpJob implements Job {
private Logger logger = Logger.getLogger(this.getClass().getName());
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
private UtilService utilService;
@Override
public void execute(JobExecutionContext jobContext)
throws JobExecutionException {
System.out.println("调度任务开始: " + format.format(new Date()));
//获取service
ServletContext context = null;
try {
context = (ServletContext) jobContext.getScheduler().getContext()
.get(QuartzServletContextListener.MY_CONTEXT_NAME);
} catch (SchedulerException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
XmlWebApplicationContext cxt = (XmlWebApplicationContext) WebApplicationContextUtils
.getWebApplicationContext(context);
utilService = (UtilService) cxt.getBean("utilService");
}
}
如果不让任务并发执行,可把实现Job接口改为实现StatefulJob接口。