Quartz+Spring 自定义做业调度(做业在DB中配置)
Quartz版本为1.8.3
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
>
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();
}
}
}
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;
}
}
其中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;
}
}
由这些代码,即可以经过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即可调度这些做业了。
欢迎关注本站公众号,获取更多信息