Quartz Job & Spring 动态任务调度
来源:互联网 发布:sharepoint是什么软件 编辑:程序博客网 时间:2024/03/29 22:55
Quartz Job & Spring
在实际项目应用中经常会用到定时任务,可通过Quartz框架轻松完成。在Web项目中,如果用Spring框架管理Quartz,在Web容器启动或关闭时自动启动、关闭Quartz中的任务,非常方便。
传统的MethodInvokingJobDetailFactoryBean
运行方式,配置复杂,且不够灵活——如果要动态改变任务的状态、cron表达式等就需要改变配置甚至代码需要重启服务器了。因此,我采取动态任务调度的方式,可自由控制任务进度,更可以显示到html页面上。
配置
只需要在Spring配置文件中加上SchedulerFactoryBean。
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="no"></bean>
这样,Spring就为我们创建了一个空的Scheduler,我们后面手动添加任务进去。
任务
我们定义一个Job类,任务都在这个Job类上执行
public class QuartzJobFactory implements Job { public void execute(JobExecutionContext context) throws JobExecutionException{ System.out.println("任务执行了"); }}
既然记录任务状态,那就需要定义一个类了,我们定义一个ScheduleJob
,
public class ScheduleJobDomain { private String jobId; //任务id private String jobName; //任务名称 /** 任务状态 */ private String jobStatus; private String quartz; //cron表达式 //省略get、set方法}
再定义一个Service
/** * 管理quartz任务的service */public interface ScheduleJobService { //获取所有计划中的任务 List<ScheduleJobDomain> getPlanJobs() throws SchedulerException; //获取所有运行中的任务 List<ScheduleJobDomain> getRunningJobs() throws SchedulerException; //暂停任务 void pauseJob(ScheduleJobDomain scheduleJob) throws SchedulerException; //恢复任务 void resumeJob(ScheduleJobDomain scheduleJob) throws SchedulerException; //删除任务 void deleteJob(ScheduleJobDomain scheduleJob) throws SchedulerException; //立即运行任务 ,只会运行一次 void runOnce(ScheduleJobDomain scheduleJob) throws SchedulerException; //更新任务的时间表达式 void updateExpression(ScheduleJobDomain job,String expression) throws SchedulerException; //添加任务 void addJob(ScheduleJobDomain scheduleJob) throws SchedulerException;}
Service的实现类如下
@Servicepublic class ScheduleJobServiceImpl implements ScheduleJobService { @Autowired private Scheduler scheduler; @Override public List<ScheduleJobDomain> getPlanJobs() throws SchedulerException { GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup(); Set<JobKey> jobKeys = scheduler.getJobKeys(matcher); List<ScheduleJobDomain> jobList = new ArrayList<ScheduleJobDomain>(); for(JobKey jobKey : jobKeys){ List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey); for (Trigger trigger : triggers){ ScheduleJobDomain job = (ScheduleJobDomain) trigger.getJobDataMap().get("scheduleJob"); Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey()); job.setJobStatus(triggerState.name()); if (trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger) trigger; String cronExpression = cronTrigger.getCronExpression(); job.setQuartz(cronExpression); } jobList.add(job); } } return jobList; } @Override public List<ScheduleJobDomain> getRunningJobs() throws SchedulerException { List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs(); List<ScheduleJobDomain> jobList = new ArrayList<ScheduleJobDomain>(); for (JobExecutionContext executingJob : executingJobs){ Trigger trigger = executingJob.getTrigger(); ScheduleJobDomain job = (ScheduleJobDomain) trigger.getJobDataMap().get("scheduleJob"); Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey()); job.setJobStatus(triggerState.name()); if (trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger) trigger; String cronExpression = cronTrigger.getCronExpression(); job.setQuartz(cronExpression); } jobList.add(job); } return jobList; } @Override public void pauseJob(ScheduleJobDomain scheduleJob) throws SchedulerException { JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.pauseJob(jobKey); } @Override public void resumeJob(ScheduleJobDomain scheduleJob) throws SchedulerException { JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.resumeJob(jobKey); } @Override public void deleteJob(ScheduleJobDomain scheduleJob) throws SchedulerException { JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.deleteJob(jobKey); } @Override public void runOnce(ScheduleJobDomain scheduleJob) throws SchedulerException { JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.triggerJob(jobKey); } @Override public void updateExpression(ScheduleJobDomain scheduleJob, String expression) throws SchedulerException { TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(expression); trigger = trigger.getTriggerBuilder().withIdentity(triggerKey) .withSchedule(scheduleBuilder).build(); scheduler.rescheduleJob(triggerKey, trigger); } @Override public void addJob(ScheduleJobDomain scheduleJob) throws SchedulerException { TriggerKey key = TriggerKey.triggerKey(scheduleJob.getJobName(),scheduleJob.getJobGroup()); Trigger trigger = scheduler.getTrigger(key); if(trigger == null){ //在创建任务时如果不存在新建一个 JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class) .withIdentity(scheduleJob.getJobName(),scheduleJob.getJobGroup()).build(); jobDetail.getJobDataMap().put("scheduleJob",scheduleJob); //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getQuartz()); //按新的cronExpression表达式构建一个新的trigger trigger = TriggerBuilder.newTrigger().withIdentity(scheduleJob.getJobName(),scheduleJob.getJobGroup()) .withSchedule(scheduleBuilder).build(); trigger.getJobDataMap().put("scheduleJob",scheduleJob); scheduler.scheduleJob(jobDetail,trigger); }else{ // Trigger已存在,那么更新相应的定时设置 //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getQuartz()); trigger = TriggerBuilder.newTrigger().withIdentity(key).withSchedule(scheduleBuilder).build(); trigger.getJobDataMap().put("scheduleJob",scheduleJob); //重新执行 scheduler.rescheduleJob(key,trigger); } }
这样,我们在页面Controller中,就可以直接使用BankJobService来管理任务的状态了。
附
在Job中如何得到Spring的Bean
由于Job对象是Quartz创建的,它没有被注册到Spring容器中,因此无法直接通过@Autowired得到Spring的Bean对象,解决方式是从BankJobServiceImpl中拿到需要的SpringBean,然后在addJob时放到JobDetail里面去。
比如拿到Mybatis的SqlSessionTemplate。
public class BankJobServiceImpl{ @Autowired private SqlSessionTemplate sqlSessionTemplate;}
在addJob方法里面, 修改
JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class) .withIdentity(scheduleJob.getJobName(),scheduleJob.getJobGroup()).build();jobDetail.getJobDataMap().put("sqlSessionTemplate",sqlSessionTemplate);
然后在QuartzJobFactory中
public void execute(JobExecutionContext context) throws JobExecutionException{ SqlSessionTemplate sqlSessionTemplate = (SqlSessionTemplate) context.getMergedJobDataMap().get("sqlSessionTemplate");}
阅读全文
0 0
- Quartz Job & Spring 动态任务调度
- Spring+quartz 动态任务调度
- Spring + Quartz动态任务调度
- spring+quartz实现动态任务调度
- 动态Quartz任务调度(Spring结合Quartz)
- Spring + Quartz任务调度实战之动态作业调度
- Spring + Quartz任务调度实战之动态作业调度
- Spring + Quartz任务调度实战之动态作业调度
- spring quartz任务调度
- Spring Quartz 任务调度
- Spring Quartz 任务调度
- spring quartz 任务调度
- spring quartz任务调度
- spring Quartz任务调度
- Quartz 调度,添加,修改,删除 任务,Job
- 任务调度(Quartz Enterprise Job Scheduler)
- 任务调度(Quartz Enterprise Job Scheduler)
- Spring整合Quartz实现动态任务调度定时器
- Codeforces 343D-Water Tree
- maven 的聚合
- Eclipse启动参数设置和配置文件修改
- CDH的hive版本和apache的hive之间的关系
- c++条件语句的实战编程
- Quartz Job & Spring 动态任务调度
- Properties总结
- 连接 iPhone的常用命令
- shell脚本之踩过的坑
- thymeleaf基础知识总结
- linux如何修改固定IP
- 如何调高或降低海拔高程基准面
- Eclipse快捷键大全
- java面试题