Spring版本为2.5
自定义作业表 QRTZ_JOB。
其中定义 作业标识、作业名称、类名、触发器名称、触发器脚本等。
下面看看在Spring中如何配置Quartz。
applicationContext.xml
<?
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:aop ="http://www.springframework.org/schema/aop"
xmlns:tx ="http://www.springframework.org/schema/tx"
xmlns:context ="http://www.springframework.org/schema/context"
xsi:schemaLocation ="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-lazy-init ="false" >
< context:component-scan base-package ="com.jn" />
< tx:advice id ="txAdvice" transaction-manager ="txManager" >
< tx:attributes >
< tx:method name ="insert*" propagation ="REQUIRED" />
< tx:method name ="del*" propagation ="REQUIRED" />
< tx:method name ="update*" propagation ="REQUIRED" />
< tx:method name ="*" read-only ="true" />
</ tx:attributes >
</ tx:advice >
< aop:config >
< aop:pointcut id ="allManagerMethod" expression ="execution(* com.jn.*.*(..))" />
< aop:advisor advice-ref ="txAdvice" pointcut-ref ="allManagerMethod" />
</ aop:config >
< bean id ="txManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
< property name ="dataSource" ref ="proxoolDataSource" />
</ bean >
< bean id ="propertyConfigurer"
class ="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
< property name ="locations" >
< list >
< value > classpath:jdbc.properties </ value >
</ list >
</ property >
</ bean >
< bean id ="proxoolDataSource" class ="org.apache.commons.dbcp.BasicDataSource" destroy-method ="close" >
< property name ="driverClassName" value ="${driver}" />
< property name ="url" value ="${dburl}" />
< property name ="username" value ="${username}" />
< property name ="password" value ="${password}" />
</ bean >
< bean id ="sqlMapClient" class ="org.springframework.orm.ibatis.SqlMapClientFactoryBean" >
< property name ="dataSource" >
< ref local ="proxoolDataSource" />
</ property >
< property name ="configLocation" >
< value > classpath:sql-map-config.xml </ value >
</ property >
</ bean >
< bean name ="quartzScheduler" lazy-init ="true" class ="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
< property name ="dataSource" ref ="proxoolDataSource" />
< property name ="applicationContextSchedulerContextKey" value ="applicationContextKey" />
< property name ="configLocation" value ="classpath:quartz.properties" />
</ bean >
</ beans >
< beans
xmlns ="http://www.springframework.org/schema/beans"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop ="http://www.springframework.org/schema/aop"
xmlns:tx ="http://www.springframework.org/schema/tx"
xmlns:context ="http://www.springframework.org/schema/context"
xsi:schemaLocation ="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-lazy-init ="false" >
< context:component-scan base-package ="com.jn" />
< tx:advice id ="txAdvice" transaction-manager ="txManager" >
< tx:attributes >
< tx:method name ="insert*" propagation ="REQUIRED" />
< tx:method name ="del*" propagation ="REQUIRED" />
< tx:method name ="update*" propagation ="REQUIRED" />
< tx:method name ="*" read-only ="true" />
</ tx:attributes >
</ tx:advice >
< aop:config >
< aop:pointcut id ="allManagerMethod" expression ="execution(* com.jn.*.*(..))" />
< aop:advisor advice-ref ="txAdvice" pointcut-ref ="allManagerMethod" />
</ aop:config >
< bean id ="txManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
< property name ="dataSource" ref ="proxoolDataSource" />
</ bean >
< bean id ="propertyConfigurer"
class ="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
< property name ="locations" >
< list >
< value > classpath:jdbc.properties </ value >
</ list >
</ property >
</ bean >
< bean id ="proxoolDataSource" class ="org.apache.commons.dbcp.BasicDataSource" destroy-method ="close" >
< property name ="driverClassName" value ="${driver}" />
< property name ="url" value ="${dburl}" />
< property name ="username" value ="${username}" />
< property name ="password" value ="${password}" />
</ bean >
< bean id ="sqlMapClient" class ="org.springframework.orm.ibatis.SqlMapClientFactoryBean" >
< property name ="dataSource" >
< ref local ="proxoolDataSource" />
</ property >
< property name ="configLocation" >
< value > classpath:sql-map-config.xml </ value >
</ property >
</ bean >
< bean name ="quartzScheduler" lazy-init ="true" class ="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
< property name ="dataSource" ref ="proxoolDataSource" />
< property name ="applicationContextSchedulerContextKey" value ="applicationContextKey" />
< property name ="configLocation" value ="classpath:quartz.properties" />
</ bean >
</ beans >
Main.java
package
com.jn.common;
import com.jn.qrtz.job.JobManager;
import com.jn.spring.BeanFactory;
/**
* 启动类
* @author l
*/
public class Main {
/**
* 启动函数
* @param args
*/
public static void main(String[] args) {
try {
JobManager mgr = (JobManager)BeanFactory.factory().getBean("jobManager");
mgr.init();
mgr.dispatch();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
import com.jn.qrtz.job.JobManager;
import com.jn.spring.BeanFactory;
/**
* 启动类
* @author l
*/
public class Main {
/**
* 启动函数
* @param args
*/
public static void main(String[] args) {
try {
JobManager mgr = (JobManager)BeanFactory.factory().getBean("jobManager");
mgr.init();
mgr.dispatch();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
JobManager.java
package
com.jn.qrtz.job;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.jn.persistence.QrtzDaoImpl;
import com.jn.qrtz.JobConfig;
import com.jn.qrtz.service.SchedulerServiceImpl;
/**
* 作业管理类
*
* @author l
*/
@Component( " jobManager " )
@Scope( " singleton " )
public class JobManager {
private Logger log = Logger.getLogger(JobManager.class);
@Autowired(required = true)
private QrtzDaoImpl qrtzDao;
@Autowired(required = true)
private SchedulerServiceImpl schedulerService;
/** 作业列表 */
private List<JobConfig> allJobs = new ArrayList<JobConfig>();
/**
* 初始化作业列表
*/
public synchronized void init() {
try {
allJobs = qrtzDao.queryAllJobs();
log.info("作业初始化完成。");
}
catch (SQLException e) {
log.error("初始化作业失败。" + e.getMessage());
}
}
/**
* 系统启动时派发作业
*/
public void dispatch() {
for (JobConfig job : allJobs) {
try {
schedulerService.schedule(job);
}
catch (Exception e) {
e.printStackTrace();
log.error(job.toString() + "派发失败。" + e.getMessage());
}
}
}
public SchedulerServiceImpl getSchedulerService() {
return schedulerService;
}
public void setSchedulerService(
@Qualifier("schedulerService") SchedulerServiceImpl schedulerService) {
this.schedulerService = schedulerService;
}
public QrtzDaoImpl getQrtzDao() {
return qrtzDao;
}
public void setQrtzDao(@Qualifier("qrtzDao") QrtzDaoImpl qrtzDao) {
this.qrtzDao = qrtzDao;
}
}
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.jn.persistence.QrtzDaoImpl;
import com.jn.qrtz.JobConfig;
import com.jn.qrtz.service.SchedulerServiceImpl;
/**
* 作业管理类
*
* @author l
*/
@Component( " jobManager " )
@Scope( " singleton " )
public class JobManager {
private Logger log = Logger.getLogger(JobManager.class);
@Autowired(required = true)
private QrtzDaoImpl qrtzDao;
@Autowired(required = true)
private SchedulerServiceImpl schedulerService;
/** 作业列表 */
private List<JobConfig> allJobs = new ArrayList<JobConfig>();
/**
* 初始化作业列表
*/
public synchronized void init() {
try {
allJobs = qrtzDao.queryAllJobs();
log.info("作业初始化完成。");
}
catch (SQLException e) {
log.error("初始化作业失败。" + e.getMessage());
}
}
/**
* 系统启动时派发作业
*/
public void dispatch() {
for (JobConfig job : allJobs) {
try {
schedulerService.schedule(job);
}
catch (Exception e) {
e.printStackTrace();
log.error(job.toString() + "派发失败。" + e.getMessage());
}
}
}
public SchedulerServiceImpl getSchedulerService() {
return schedulerService;
}
public void setSchedulerService(
@Qualifier("schedulerService") SchedulerServiceImpl schedulerService) {
this.schedulerService = schedulerService;
}
public QrtzDaoImpl getQrtzDao() {
return qrtzDao;
}
public void setQrtzDao(@Qualifier("qrtzDao") QrtzDaoImpl qrtzDao) {
this.qrtzDao = qrtzDao;
}
}
其中QrtzDaoImpl对象是用于从QRTZ_JOB表中取得作业列表,并将作业封装为JobConfig对象。
SchedulerServiceImpl对象用于派发Job。
SchedulerServiceImpl.java
package
com.jn.qrtz.service;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.jn.qrtz.JobConfig;
import com.jn.qrtz.job.WorkDispatcher;
/**
* 作业派发、移除类
* @author l
*/
@Component( " schedulerService " )
public class SchedulerServiceImpl {
@Autowired
private Scheduler scheduler;
/**
* 移除作业
* @param config
* @return
* @throws SchedulerException
*/
public boolean remove(JobConfig config) throws SchedulerException {
if(config == null) {
return false;
}
return removeJob(config.getJobName(), config.getJobGroup());
}
/**
* 派发作业
* @param config
* @throws Exception
*/
public void schedule(JobConfig config) throws Exception {
String triggerName = config.getTriggerName();
String triggerGroup = config.getTriggerGroup();
String cronStr = config.getTriggerScript();
String jobName = config.getJobName();
String jobGroup = config.getJobGroup();
JobDetail jobDetail = new JobDetail(jobName, jobGroup, WorkDispatcher.class);
jobDetail.getJobDataMap().put(JobConfig.EXEC_INFO, config.cloneInfo());
schedule(triggerName, triggerGroup, cronStr, jobDetail);
}
/**
* 派发作业
* @param name
* @param group
* @param cronStr
* @param jobDtl
* @throws Exception
*/
private void schedule(String name, String group, String cronStr, JobDetail jobDtl)
throws Exception {
CronTrigger cronTrigger = new CronTrigger(name, group, jobDtl.getName(), jobDtl.getGroup(),
cronStr);
scheduler.scheduleJob(jobDtl, cronTrigger);
}
/**
* 移除作业
* @param jobName
* @param group
* @return
* @throws SchedulerException
*/
private boolean removeJob(String jobName, String group) throws SchedulerException {
scheduler.pauseJob(jobName, group);
return scheduler.deleteJob(jobName, group);
}
@Autowired
public void setScheduler(@Qualifier("quartzScheduler") Scheduler scheduler) {
this.scheduler = scheduler;
}
}
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.jn.qrtz.JobConfig;
import com.jn.qrtz.job.WorkDispatcher;
/**
* 作业派发、移除类
* @author l
*/
@Component( " schedulerService " )
public class SchedulerServiceImpl {
@Autowired
private Scheduler scheduler;
/**
* 移除作业
* @param config
* @return
* @throws SchedulerException
*/
public boolean remove(JobConfig config) throws SchedulerException {
if(config == null) {
return false;
}
return removeJob(config.getJobName(), config.getJobGroup());
}
/**
* 派发作业
* @param config
* @throws Exception
*/
public void schedule(JobConfig config) throws Exception {
String triggerName = config.getTriggerName();
String triggerGroup = config.getTriggerGroup();
String cronStr = config.getTriggerScript();
String jobName = config.getJobName();
String jobGroup = config.getJobGroup();
JobDetail jobDetail = new JobDetail(jobName, jobGroup, WorkDispatcher.class);
jobDetail.getJobDataMap().put(JobConfig.EXEC_INFO, config.cloneInfo());
schedule(triggerName, triggerGroup, cronStr, jobDetail);
}
/**
* 派发作业
* @param name
* @param group
* @param cronStr
* @param jobDtl
* @throws Exception
*/
private void schedule(String name, String group, String cronStr, JobDetail jobDtl)
throws Exception {
CronTrigger cronTrigger = new CronTrigger(name, group, jobDtl.getName(), jobDtl.getGroup(),
cronStr);
scheduler.scheduleJob(jobDtl, cronTrigger);
}
/**
* 移除作业
* @param jobName
* @param group
* @return
* @throws SchedulerException
*/
private boolean removeJob(String jobName, String group) throws SchedulerException {
scheduler.pauseJob(jobName, group);
return scheduler.deleteJob(jobName, group);
}
@Autowired
public void setScheduler(@Qualifier("quartzScheduler") Scheduler scheduler) {
this.scheduler = scheduler;
}
}
由这些代码,便可以通过Quartz框架去调度 我们定义在QRTZ_JOB表中的作业了。
由于Quartz框架本身依赖一些表,其中我们执行的作业,同样会被框架保存在那些它所依赖的表中,
如:qrtz_job_details表。
当Spring加载quartzScheduler时,Quartz框架会被自动启动并调度保存在qrtz_job_details表中的作业。
所以再次启动时,应先将 Quartz依赖的表清空。
当然这个操作也可以被集成在代码中。
还有另外一种方案可实现此的功能,便是重写org.springframework.scheduling.quartz.SchedulerFactoryBean类,
自定义类继承此类,在自定义的类中注入自己的对象,在其中取得 作业列表,
并生成Trigger对象数组,调用 org.springframework.scheduling.quartz.SchedulerFactoryBean 类的setTriggers(Trigger[]) 方法。
设置好Trigger数据。
最后再 调用Scheduler的start()方法,Quartz便可调度这些作业了。