quartz原理参考:https://blog.csdn.net/xlxxcc/article/details/52104463
https://www.cnblogs.com/davidwang456/p/10329616.html
这里实现了定时任务动态变更. job类可以引用spring-bean功能
pom文件:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
1:创建一个JobFactory类继承于AdaptableJobFactory。注入AutowireCapableBeansFactory.这样就完成Spring对Job的注入功能
package com.ss.re.quartz;
import org.quartz.impl.JobDetailImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class QuartzConfig {
@Autowired
private JobFactory jobFactory;
@Bean(name = "schedulerFactoryBean")
public SchedulerFactoryBean createSchedulerFactoryBean(){
SchedulerFactoryBean schedulerFactoryBean=new SchedulerFactoryBean();
schedulerFactoryBean.setOverwriteExistingJobs(true);
schedulerFactoryBean.setJobFactory(jobFactory);
return schedulerFactoryBean;
}
@Bean
public JobDetailImpl createJobDetailsImpl(){
return new JobDetailImpl();
}
}
2.添加一个QuartzConfig类。对Scheduer进行重新配置设置Scheduler的JobFactory使用我们自己创建的JobFactory
package com.ss.re.quartz;
import org.quartz.impl.JobDetailImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class QuartzConfig {
@Autowired
private JobFactory jobFactory;
@Bean(name = "schedulerFactoryBean")
public SchedulerFactoryBean createSchedulerFactoryBean(){
SchedulerFactoryBean schedulerFactoryBean=new SchedulerFactoryBean();
schedulerFactoryBean.setOverwriteExistingJobs(true);
schedulerFactoryBean.setJobFactory(jobFactory);
return schedulerFactoryBean;
}
@Bean
public JobDetailImpl createJobDetailsImpl(){
return new JobDetailImpl();
}
}
3.定义一个job类, 实现org.quartz.job接口,并重写执行方法
package com.ss.re.quartz;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import com.ss.re.service.RuleProcessService;
@Component
public class RuleTriggerJob implements Job{
@Autowired
private RuleProcessService service;
@Override
public void execute(JobExecutionContext jobExecutionContext) {
System.out.println(new Date() + "定时任务执行");
System.out.println(jobExecutionContext.getJobDetail().getJobDataMap().get("fiterName"));
service.testInject();
}
}
4.定时任务管理类,并实现了对job任务的操作
package com.ss.re.quartz;
import javax.annotation.PostConstruct;
import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
@Component
public class QuartzManager {
private static Logger logger = Logger.getLogger(QuartzManager.class);
@Autowired
@Qualifier("schedulerFactoryBean")//多个实现类时指定名字
private SchedulerFactoryBean schedulerFactoryBean;
@PostConstruct
public void registry(){
scheduler = schedulerFactoryBean.getScheduler();
}
private static Scheduler scheduler;
private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
/**
* @Description: 添加一个定时任务
*
* @param jobName 任务名
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param jobClass 任务
* @param cron 时间设置,参考quartz说明文档
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void addJob(String jobName, String jobGroupName,
String triggerName, String triggerGroupName, String cron,String fiterName) {
try {
Scheduler sched = scheduler;
// 任务名,任务组,任务执行类
JobDetail jobDetail= JobBuilder.newJob(RuleTriggerJob.class).withIdentity(jobName, jobGroupName)
.usingJobData("fiterName", fiterName)
.build();
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建Trigger对象
CronTrigger trigger = (CronTrigger) triggerBuilder.build();
// 调度容器设置JobDetail和Trigger
sched.scheduleJob(jobDetail, trigger);
// 启动
if (!sched.isShutdown()) {
sched.start();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 修改一个任务的触发时间
*
* @param jobName
* @param jobGroupName
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param cron 时间设置,参考quartz说明文档
*/
public static void modifyJobTime(String jobName,
String jobGroupName, String triggerName, String triggerGroupName, String cron) {
try {
Scheduler sched = scheduler;
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(cron)) {
/** 方式一 :调用 rescheduleJob 开始 */
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建Trigger对象
trigger = (CronTrigger) triggerBuilder.build();
// 方式一 :修改一个任务的触发时间
sched.rescheduleJob(triggerKey, trigger);
/** 方式一 :调用 rescheduleJob 结束 */
/** 方式二:先删除,然后在创建一个新的Job */
//JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
//Class<? extends Job> jobClass = jobDetail.getJobClass();
//removeJob(jobName, jobGroupName, triggerName, triggerGroupName);
//addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
/** 方式二 :先删除,然后在创建一个新的Job */
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 移除一个任务
*
* @param jobName
* @param jobGroupName
* @param triggerName
* @param triggerGroupName
*/
public static void removeJob(String jobName, String jobGroupName,
String triggerName, String triggerGroupName) {
try {
Scheduler sched = scheduler;
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
sched.pauseTrigger(triggerKey);// 停止触发器
sched.unscheduleJob(triggerKey);// 移除触发器
sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:启动所有定时任务
*/
public static void startJobs() {
try {
Scheduler sched = scheduler;
sched.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:关闭所有定时任务
*/
public static void shutdownJobs() {
try {
Scheduler sched = scheduler;
if (!sched.isShutdown()) {
sched.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 安全关闭
* @throws SchedulerException
*/
public static void safeShutdown() throws SchedulerException {
int executingJobSize = scheduler.getCurrentlyExecutingJobs().size();
logger.info("安全关闭 当前还有" + executingJobSize + "个任务正在执行,等待完成后关闭");
//等待任务执行完后安全关闭
scheduler.shutdown(true);
logger.info("安全关闭 成功");
}
}
5.测试方法
public class Test {
public static String JOB_NAME = "动态任务调度";
public static String TRIGGER_NAME = "动态任务触发器";
public static String JOB_GROUP_NAME = "XLXXCC_JOB_GROUP";
public static String TRIGGER_GROUP_NAME = "XLXXCC_JOB_GROUP";
public static void main(String[] args) {
/*trigger job名称可以自由定义*/
try {
System.out.println("【系统启动】开始(每1秒输出一次)...");
QuartzManager.addJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME, MyJob.class, "0/1 * * * * ?");
Thread.sleep(5000);
System.out.println("【修改时间】开始(每5秒输出一次)...");
QuartzManager.modifyJobTime(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME, "0/5 * * * * ?");
Thread.sleep(6000);
System.out.println("【移除定时】开始...");
QuartzManager.removeJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME);
System.out.println("【移除定时】成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}