1. 定义数据源
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.pwd}"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.initialPoolSize}" />
<property name="minIdle" value="${jdbc.minPoolSize}"/>
<property name="maxActive" value="${jdbc.maxPoolSize}"/>
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="10000"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT '1' " />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize"value="20" />
</bean>
2. 定义schedulerFactoryBean
<bean name="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<!-- spring 管理的service注入-->
<propertyname="schedulerContextAsMap">
<map>
<entrykey="myService "value-ref="myService"/>
</map>
</property>
<property name="applicationContextSchedulerContextKey"value="applicationContext" />
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">myJob</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">20</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
<prop key="org.quartz.jobStore.misfireThreshold">120000</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">15000</prop>
<prop key="org.quartz.jobStore.maxMisfiresToHandleAtATime">1</prop>
<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
</props>
</property>
</bean>
3. 初始化作业任务
public class QrtzJobInit {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
SchedulerFactoryBean schedulerFactoryBean;
@Autowired
QrtzJobLogic qrtzJobLogic;
public void init(){
Scheduler scheduler = schedulerFactoryBean.getScheduler();
QrtzJobPo cond = new QrtzJobPo();
cond.setJobStatus(EnumJobState.NORMAL.getKey());
try {
ResultPOListBean<QrtzJobPo> resultPOListBean = qrtzJobLogic.queryQrtzJobListByCond(cond);
if (resultPOListBean.getValue() == null || resultPOListBean.getValue().size() == 0)
return;
for (QrtzJobPo job : resultPOListBean.getValue()) {
addJob(job,scheduler);
}
if(scheduler.isShutdown())
scheduler.startDelayed(20);
logger.error("任务加载完成,size:{}",resultPOListBean.getValue().size());
} catch (Exception e) {
logger.error("异常:"+e);
}
}
private void addJob(QrtzJobPo job,Scheduler scheduler) {
try {
if (job == null) {
return;
}
if (!CronExpression.isValidExpression(job.getCronExpression())) {
logger.error("时间表达式错误,jobname={},jobgroup={},cronExpression={}", job.getJobName(), job.getJobGroup(),
job.getCronExpression());
return;
}
TriggerKey triggerKey = TriggerUtils.getTriggerKey(job);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (null == trigger) {
JobDetail jobDetail = JobUtils.getJob(job);
trigger = TriggerUtils.newTrigger(job);
scheduler.scheduleJob(jobDetail, trigger);
} else {
trigger =TriggerUtils.getTrigger(trigger, job);
scheduler.rescheduleJob(triggerKey, trigger);
}
} catch (SchedulerException e) {
logger.error("异常:"+e);
}
return;
}
4. 作业任务执行
public class QrtzJobFactory extends BaseJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
SchedulerContext schedulerContext = context.getScheduler().getContext();
JobDataMap map = context.getMergedJobDataMap();
Set<String> keys = map.keySet();
for (String key : keys) {
QrtzJobPo scheduleJob = (QrtzJobPo) context.getMergedJobDataMap().get(key);
logger.info("执行任务 :{} ,开始.", scheduleJob.getJobName());
executor(scheduleJob,schedulerContext);
logger.info("执行任务 :{} ,完成.", scheduleJob.getJobName());
}
Thread.sleep(60000);
} catch (InterruptedException | SchedulerException e) {
logger.error("异常:"+e);
}
}
}
executor方法说明,利用spring的反射工具实现动态执行任务
参考文章
1. http://itindex.net/detail/53315-spring-quartz-%E7%AE%A1%E7%90%86
2. http://itindex.net/detail/52939-quartz-%E9%9B%86%E7%BE%A4-spring
3. http://www.cnblogs.com/nick-huang/p/4862732.html
4. https://nkcoder.github.io/blog/20140627/quartz-tutorial-job-jobdetail/