您的位置:首页 > 编程语言 > Java开发

Spring与Quartz实现动态更新定时任务

2017-03-01 10:01 453 查看
applicationContext-quartz.xml配置:

<!--
任务调度测试实现一 :
自定义的任务对象com.bocloud.equipment.test.ExampleJob
必须继承QuartzJobBean类,实现抽象方法executeInternal
每次执行任务时,都会新创建一个任务对象.
-->
<bean id="myJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<!--
属性jobClass不能通过ref来指定为exampleJob对象,该属性接收的是Class类型的参数
进行任务调度时,每次都是一个新的jobClass对象去执行executeInternal方法
-->
<property name="jobClass" value="com.bocloud.equipment.test.ComputerInfoGatherJob" />
</bean>

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="myJobDetail" />
<property name="cronExpression" value="0/10 * * * * ?" />
</bean>

<bean id="computerInfoGatherScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>我们只需要专注于QuartzJobBean子类中的executeInternal方法的实现,该方法里只需要放置我们需要定期执行的任务代码即可
<!--
任务调试实现测试二 :
属性targetObject:指定执行任务的对象
属性targetMethod:指定执行任务的方法,该方法必须是无参方法
-->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="computerService" />
<property name="targetMethod" value="list" />
</bean>

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="jobDetail" />
<property name="cronExpression" value="0/10 * * * * ?" />
</bean>

<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>

targetObject引用参考的对象,就是Spring框架帮我们生成好的自定义的任务bean对象,不过要注意的是,targetMehthod指定的方法必须是无参的(Spring也支持可以带有参数的任务方法,具体的没注意,以后搞明白了再更新上来,不过一般我们执行定期任务时都不需要动态参数)

package com.bocloud.equipment.test;

import java.text.ParseException;
import java.util.Date;

import org.quartz.CronTrigger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdScheduler;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;

import com.bocloud.equipment.service.ComputerServiceImpl;

public class ComputerInfoGatherJob extends QuartzJobBean {

private static long count = 0L;

@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println("*******************************");
count++;
System.out.println(new Date() + "\t:任务调度开始第" + count + "次");

WebApplicationContext webContext = ContextLoaderListener.getCurrentWebApplicationContext();
ComputerServiceImpl csi = webContext.getBean(ComputerServiceImpl.class);
/*
* 更改任务调度的周期时间:
* 1,不要调用StdScheduler的shutdown()方法,shutdown()以后无法再start()
* 2,可使用standby()暂停调度任务,再start()
* 3,设置cron后,要调用rescheduleJob(TriggerKey triggerKey, Trigger newTrigger)
*/

/*
* 这里获取SchedulerFactoryBean时,不要通过getBean(Class<T> requiredType)
* 或getBean(String name, Class<T> requiredType)
* 否则会提示转型错误:
* org.quartz.impl.StdScheduler无法转型为指定的需要类型:
* org.springframework.scheduling.quartz.SchedulerFactoryBean
* 直接使用getBean(String name)再强转为org.quartz.impl.StdScheduler即可
*/
StdScheduler scheduler = (StdScheduler)webContext.getBean("computerInfoGatherScheduler");
if (count == 2) {
System.out.println("Computer信息采集任务暂停!");
try {
//获取此调度器中名称为cronTrigger(配置文件中CronTriggerFactoryBean的名称)的Trigger对象
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger("cronTrigger", Scheduler.DEFAULT_GROUP);
System.out.println("设置Computer信息采集任务周期为:5秒");
cronTrigger.setCronExpression("0/5 * * * * ?");
/*
* public Date rescheduleJob(String triggerName, String groupName, Trigger newTrigger) throws SchedulerException
* triggerName:要被替换的Trigger的名称
* groupName:要被替换的Trigger的组名
* newTrigger:要新保存的Trigger对象
* 返回:如果没找到triggerName则返回空,否则返回第一次触发任务的时间
*/
Date date = scheduler.rescheduleJob("cronTrigger", Scheduler.DEFAULT_GROUP, cronTrigger);
System.out.println("=========Computer信息采集任务重新开始=========");
if (date == null) {
throw new RuntimeException("更改任务周期后,重新调度任务失败!!!");
}
} catch (SchedulerException e) {
System.out.println("获取CronTrigger对象时出现异常");
e.printStackTrace();
} catch (ParseException e) {
System.out.println("解析cron表达式时出现异常");
e.printStackTrace();
}
}

if (count == 4) {
System.out.println("暂停任务调度!!10秒后重新开始");
//暂停调度任务:调度器中的所有Trigger对应的任务都会暂停,要暂停指定Trigger的话,调用pauseTrigger()
scheduler.standby();
try {
Thread.sleep(10000);
//判断调度器当前是否在暂停状态
if (scheduler.isInStandbyMode()) {
scheduler.start();
}
System.out.println("任务调度又重新开始");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
csi.list(0, null, null);
}

}
参考:Spring与Quartz实现定期任务
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: