依赖
org.quartz-scheduler quartz 2.2.1
任务工厂 JobFactory
// 解决SpringBoot不能再Quartz中注入Bean的问题@Componentpublic class JobFactory extends AdaptableJobFactory { /** * AutowireCapableBeanFactory接口是BeanFactory的子类 * 可以连接和填充那些生命周期不被Spring管理的已存在的bean实例 */ private AutowireCapableBeanFactory factory; public JobFactory(AutowireCapableBeanFactory factory) { this.factory = factory; } /** * 创建Job实例 */ @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { // 实例化对象 Object job = super.createJobInstance(bundle); // 进行注入(Spring管理该Bean) factory.autowireBean(job); //返回对象 return job; }}
任务调度器 Scheduler
@Configurationpublic class QuartzConfig { private JobFactory jobFactory; public QuartzConfig(JobFactory jobFactory){ this.jobFactory = jobFactory; } /** * 配置SchedulerFactoryBean * * 将一个方法产生为Bean并交给Spring容器管理 */ @Bean public SchedulerFactoryBean schedulerFactoryBean() { // Spring提供SchedulerFactoryBean为Scheduler提供配置信息,并被Spring容器管理其生命周期 SchedulerFactoryBean factory = new SchedulerFactoryBean(); // 设置自定义Job Factory,用于Spring管理Job bean factory.setJobFactory(jobFactory); return factory; } @Bean(name = "scheduler") public Scheduler scheduler() { return schedulerFactoryBean().getScheduler(); }}
QuartzManager 工具类
@Servicepublic class QuartzManager { private Scheduler scheduler; public QuartzManager(Scheduler scheduler){ this.scheduler = scheduler; } /** * 添加一个定时任务 * * @param jobName 任务名 * @param jobGroupName 任务组名 * @param triggerName 触发器名 * @param triggerGroupName 触发器组名 * @param jobClass 任务 * @param cron 时间设置,参考quartz说明文档 */ @SuppressWarnings({ "unchecked", "rawtypes" }) public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String cron, Mapparams) { try { // 任务名,任务组,任务执行类 JobDetail job = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build(); // 任务参数 job.getJobDataMap().putAll(params); // 触发器 TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger(); // 触发器名,触发器组 triggerBuilder.withIdentity(triggerName, triggerGroupName); triggerBuilder.startNow(); // 触发器时间设定 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); // 创建Trigger对象 CronTrigger trigger = (CronTrigger) triggerBuilder.build(); // 调度容器设置JobDetail和Trigger scheduler.scheduleJob(job, trigger); // 启动 if (!scheduler.isShutdown()) { scheduler.start(); } } catch (Exception e) { throw new RuntimeException(e); } } /** * 修改一个任务的触发时间 * * @param triggerName 触发器名 * @param triggerGroupName 触发器组名 * @param cron 时间设置,参考quartz说明文档 */ public void modifyJobTime(String triggerName, String triggerGroupName, String cron) { try { TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); if (trigger == null) { return; } String oldTime = trigger.getCronExpression(); if (!oldTime.equalsIgnoreCase(cron)) { // 触发器 TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger(); // 触发器名,触发器组 triggerBuilder.withIdentity(triggerName, triggerGroupName); triggerBuilder.startNow(); // 触发器时间设定 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); // 创建Trigger对象 trigger = (CronTrigger) triggerBuilder.build(); // 方式一 :修改一个任务的触发时间 scheduler.rescheduleJob(triggerKey, trigger); } } catch (Exception e) { throw new RuntimeException(e); } } /** * 移除一个任务 * * @param jobName 任务名 * @param jobGroupName 任务组名 * @param triggerName 触发器名 * @param triggerGroupName 触发器组名 */ public void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) { try { TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); // 停止触发器 scheduler.pauseTrigger(triggerKey); // 移除触发器 scheduler.unscheduleJob(triggerKey); // 删除任务 scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName)); } catch (Exception e) { throw new RuntimeException(e); } } /** * 获取任务是否存在 * * STATE_BLOCKED 4 阻塞 * STATE_COMPLETE 2 完成 * STATE_ERROR 3 错误 * STATE_NONE -1 不存在 * STATE_NORMAL 0 正常 * STATE_PAUSED 1 暂停 * */ public Boolean notExists(String triggerName, String triggerGroupName) { try { return scheduler.getTriggerState(TriggerKey.triggerKey(triggerName, triggerGroupName)) == Trigger.TriggerState.NONE; } catch (Exception e) { throw new RuntimeException(e); } }}
举个栗子
自定义任务 Job
@Servicepublic class SftpJob extends QuartzJobBean { // 该类必须为public修饰 // 该类必须含有空参数的构造器 @Value("${sftp.root.username}") private String username; @Value("${sftp.root.password}") private String password; @Value("${sftp.host}") private String host; @Value("${sftp.port}") private Integer port; @Autowired private SftpRepository sftpRepository; @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { // 传入的参数 JobDataMap params = context.getJobDetail().getJobDataMap(); ...业务逻辑... }}
管理任务
@Servicepublic class SftpTask { // 任务名前缀 private final String job_prefix = "job_"; // 任务组前缀 private final String job_group_prefix = "job_group_"; // 触发器前缀 private final String trigger_prefix = "trigger_"; // 触发组前缀 private final String trigger_group_prefix = "trigger_group_"; private QuartzManager quartzManager; public SftpTask (QuartzManager quartzManager) { this.quartzManager = quartzManager; } /** * 根据配置生成cron表达式 */ private String getCron(SftpDTO dto) { // 时 Integer hour = dto.getHour(); // 分 Integer minute = dto.getMinute(); // 每周几 Integer week = dto.getWeek(); // 每月几号 Integer day = dto.getDay(); /* 执行时间 0每天,1每周,2每月 */ Integer execType = dto.getExecType(); String cron; switch (execType) { case 0: cron = String.format("0 %s %s * * ?", minute, hour); break; case 1: week = (week + 1) % 7; cron = String.format("0 %s %s ? * %s", minute, hour, week == 0 ? 7: week); break; case 2: cron = String.format("0 %s %s %s * ?", minute, hour, day); break; default: cron = "0 0 0 * * ?"; break; } return cron; } /** * 添加定时任务 */ private void addJob(SftpDTO dto) { Long id = dto.getId(); Mapparams = Maps.newHashMap(); params.put("id", id); quartzManager.addJob( job_prefix + id, job_group_prefix + id, trigger_prefix + id, trigger_group_prefix + id, SftpJob.class, getCron(etlSftpDTO), params ); } /** * 修改定时任务 */ public void modifyJob(SftpDTO dto) { Long id = dto.getId(); if (quartzManager.notExists(trigger_prefix + id, trigger_group_prefix + id)){ // 任务不存在 addJob(dto); } else { // 任务存在 quartzManager.modifyJobTime( trigger_prefix + id, trigger_group_prefix + id, getCron(dto) ); } } /** * 移除定时任务 */ public void removeJob(Long id) { quartzManager.removeJob( job_prefix + id, job_group_prefix + id, trigger_prefix + id, trigger_group_prefix + id ); } }