Spring整合Quartz 2.2实现作业动态调度

Quartz是当前非常流行的定时任务调度框架,个人认为比Java 7中的Timer好用。重点在于,它可以很好的和Spring框架进行整合,实现更强大的功能。最近写了一个小功能涉及Spring整合Quartz实现任务动态调度,摘取代码片段分享在这里,供参考。


实现的比较简单,主要分如下几步:


1.在spring配置文件中配置Quartz的调度器

	<bean id="schedulerFactory" lazy-init="true" autowire="no"
		class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	</bean>

2.在想要进行调度的代码片段,通过获取当前ApplicationContext拿到调度器

	//获取spring里的调度器
	StdScheduler scheduler = (StdScheduler) ContextLoader.getCurrentWebApplicationContext().getBean("schedulerFactory");
		


3.然后进行触发器和作业的分配,其中MovieTask即要调度的作业

	JobDetail jobDetail= null;
	TriggerBuilder<Trigger> triggerBuilder = null;
	CronTrigger trigger = null;
		
	for (int i = 0; i < totalNum; i++) {
		//声明任务对象[任务组,任务执行类]
	        jobDetail= JobBuilder.newJob(MovieTask.class).build();
	        jobDetail.getJobDataMap().put("movieName", movieNameList.get(i));//这里是传入的参数
	        
	        //触发器配置[Cron表达式]
	        triggerBuilder = TriggerBuilder.newTrigger();
	        triggerBuilder.startNow();
	        triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(CronUtils.getRandomCronStr(date)));
	        //声明触发器对象
	        trigger = (CronTrigger)triggerBuilder.build();

	        //调度容器调度JobDetail和Trigger
	        scheduler.scheduleJob(jobDetail,trigger);
	}


4.这里可以搞一个工具类,用于将date转换为cron表达式(因为需求需要,我生成的cron表达式中秒数是随机生成的)。

public static String getRandomCronStr(Date date)throws Exception{
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		long senconds = Math.round(Math.random()*(58)+1);
		String cronStr = senconds+" "
					+calendar.get(Calendar.MINUTE)+" "
					//+Math.round(Math.random()*(58)+1)+" "
					+calendar.get(Calendar.HOUR_OF_DAY)+" "
					+calendar.get(Calendar.DATE)+" "
					+(calendar.get(Calendar.MONTH)+1)+" ? "		//Calendar的月份比实际少1
					+calendar.get(Calendar.YEAR)+" ";
		return cronStr;
	}

5.MovieTask代码


public class MovieTask implements Job{
	
	private static transient Logger log = Logger.getLogger(MovieTask.class);
	
	@Override
	public void execute(JobExecutionContext jobexecutioncontext) throws JobExecutionException {

		String movieName = jobexecutioncontext.getJobDetail().getJobDataMap().get("movieName").toString();
		
	}

}


完成以上几步,quartz动态调度基本功能就实现了。几点说明:

1.本例生成的是立即执行(cron表达式写死了执行时间)的作业,执行完毕后会自动从调度器中删除,无需手动删除;

2.对于立即执行的作业,cron表达式的实行时间一定要晚于当前时间,否则会抛出异常;

3.被调度的作业一定要实现Job接口;

4.关于作业持久化问题。quartz官方做法是在数据库中新建10张表实现的,个人觉得配置比较麻烦。在需求不是很复杂的前提下(其实大多数需要动态配置的作业都是立即执行的),可以考虑采用上面的思路实现。比如数据库建一张作业配置表(关键字段:作业classPath,cron表达式,作业状态),启一个每分钟执行一次的作业去扫这张表,扫到后添加到调度器中,然后将数据库的记录移到历史表;

5.以上解决方案都是基于单机应用实现的,如果是集群情况需要另行处理。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值