首先引入jar包,版本统一由springboot-starter-parent管理
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.3</version></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>2.2.3</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>4.1.6.RELEASE</version></dependency>
编写配置类
工厂类JobFactory
/*** 定时任务工厂类配置** @author lijun* @date 2021/11/23 11:12*/@Componentpublic class JobFactory extends AdaptableJobFactory implements ApplicationContextAware {@Autowiredprivate transient AutowireCapableBeanFactory factory;@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {// 实例化对象Object job = super.createJobInstance(bundle);// 进行注入(Spring管理该Bean)factory.autowireBean(job);//返回对象return job;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {factory = applicationContext.getAutowireCapableBeanFactory();}}
注入工厂对象及任务调度对象
/*** 定时任务配置** @author lijun* @date 2021/11/23 11:18*/@Configurationpublic class QuartzConfig {@Autowiredprivate JobFactory jobFactory;//创建调度器工厂@Bean(name = "SchedulerFactory")public SchedulerFactoryBean schedulerFactoryBean(){SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();factoryBean.setJobFactory(jobFactory);return factoryBean;}@Bean(name = "scheduler")public Scheduler scheduler() {return schedulerFactoryBean().getScheduler();}}
封装定时任务管理类 负责增加、删除、启动、暂停等功能
/*** 定时任务管理类 负责增加、删除、启动、暂停定时任务* @author lijun*/@Componentpublic class QuartzManager {private static final Logger logger = LoggerFactory.getLogger(QuartzManager.class);@Autowiredprivate Scheduler scheduler;/*** 任务组*/private static String JOB_GROUP_NAME = "任务组";/*** 触发器组*/private static String TRIGGER_GROUP_NAME = "触发器组";/*** 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名** @param jobName* 任务名* @param cls* 任务* @param time* 时间设置,参考quartz说明文档*/public void addJob(String jobName, Class<? extends Job> cls, String time) {try {logger.info("构建作业实例......");// 用于描叙Job实现类及其他的一些静态信息,构建一个作业实例JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();logger.info("创建触发器......");// 创建一个新的TriggerBuilder来规范一个触发器CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()// 给触发器起一个名字和组名.withIdentity(jobName, TRIGGER_GROUP_NAME).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {scheduler.start(); // 启动}} catch (Exception e) {shutdownJobs();throw new RuntimeException(e);}}/*** 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名 (带参数)** @param jobName* 任务名* @param cls* 任务* @param time* 时间设置,参考quartz说明文档*/public void addJob(String jobName, Class<? extends Job> cls, String time, Map<String, Object> parameter) {try {// 用于描叙Job实现类及其他的一些静态信息,构建一个作业实例JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();// 传参数jobDetail.getJobDataMap().put("parameterMap", parameter);// 创建一个新的TriggerBuilder来规范一个触发器CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()// 给触发器起一个名字和组名.withIdentity(jobName, TRIGGER_GROUP_NAME).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {// 启动scheduler.start();}} catch (Exception e) {throw new RuntimeException(e);}}/*** 添加一个定时任务** @param jobName* 任务名* @param jobGroupName* 任务组名* @param triggerName* 触发器名* @param triggerGroupName* 触发器组名* @param jobClass* 任务* @param time* 时间设置,参考quartz说明文档*/public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName,Class<? extends Job> jobClass, String time) {try {// 任务名,任务组,任务执行类JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();// 触发器CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {// 启动scheduler.start();}} catch (Exception e) {throw new RuntimeException(e);}}/*** 添加一个定时任务 (带参数)** @param jobName* 任务名* @param jobGroupName* 任务组名* @param triggerName* 触发器名* @param triggerGroupName* 触发器组名* @param jobClass* 任务* @param time* 时间设置,参考quartz说明文档*/public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName,Class<? extends Job> jobClass, String time, Map<String, Object> parameter) {try {JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) jobClass).withIdentity(jobName, jobGroupName)// 任务名,任务组,任务执行类.build();// 传参数jobDetail.getJobDataMap().put("parameterMap", parameter);// 触发器CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {scheduler.start(); // 启动}} catch (Exception e) {throw new RuntimeException(e);}}/*** 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)** @param jobName* 任务名* @param time* 新的时间设置*/public void modifyJobTime(String jobName, String time) {try {// 通过触发器名和组名获取TriggerKeyTriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);// 通过TriggerKey获取CronTriggerCronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);if (trigger == null) {return;}String oldTime = trigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {// 通过任务名和组名获取JobKeyJobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);JobDetail jobDetail = scheduler.getJobDetail(jobKey);Class<? extends Job> objJobClass = jobDetail.getJobClass();removeJob(jobName);addJob(jobName, objJobClass, time);}} catch (Exception e) {throw new RuntimeException(e);}}/*** 修改一个任务的触发时间** @param triggerName* 任务名称* @param triggerGroupName* 传过来的任务名称* @param time* 更新后的时间规则*/public void modifyJobTime(String triggerName, String triggerGroupName, String time) {try {// 通过触发器名和组名获取TriggerKeyTriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);// 通过TriggerKey获取CronTriggerCronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);if (trigger == null) {return;}CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(trigger.getCronExpression());String oldTime = trigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {// 重新构建triggertrigger = (CronTrigger) trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();// 按新的trigger重新设置job执行scheduler.rescheduleJob(triggerKey, trigger);}} catch (Exception e) {throw new RuntimeException(e);}}/*** 移除一个任务(使用默认的任务组名,触发器名,触发器组名)** @param jobName* 任务名称*/public void removeJob(String jobName) {try {// 通过触发器名和组名获取TriggerKeyTriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);// 通过任务名和组名获取JobKeyJobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);// 停止触发器scheduler.pauseTrigger(triggerKey);// 移除触发器scheduler.unscheduleJob(triggerKey);// 删除任务scheduler.deleteJob(jobKey);} 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 {// 通过触发器名和组名获取TriggerKeyTriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);// 通过任务名和组名获取JobKeyJobKey jobKey = JobKey.jobKey(jobName, jobGroupName);// 停止触发器scheduler.pauseTrigger(triggerKey);// 移除触发器scheduler.unscheduleJob(triggerKey);// 删除任务scheduler.deleteJob(jobKey);} catch (Exception e) {throw new RuntimeException(e);}}/*** 启动所有定时任务*/public void startJobs() {try {logger.info("启动定时器......");scheduler.start();} catch (Exception e) {throw new RuntimeException(e);}}/*** 关闭所有定时任务*/public void shutdownJobs() {try {if (!scheduler.isShutdown()) {logger.info("关闭定时器......");scheduler.shutdown();}} catch (Exception e) {throw new RuntimeException(e);}}}
定时任务的增删停止,此处添加定时任务方法都是通过传入自己实现的Job类,然后反射创建对象,构造JobDetail(同一个Job构造的是不同的JobDetail),最后用schedule调度任务
定时任务类
/*** 定时任务获取参数实例且执行任务** @author lijun* @date 2021/8/17 14:29*/@Componentpublic class MyJob implements Job {@Resourceprivate TaskJob taskJob;@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();Map<String,Object> parameterMap = (Map<String,Object>)jobDataMap.get("parameterMap");String type = (String)parameterMap.get("type");if("task1".equals(type)){taskJob.task1();}else if("task2".equals(type)){taskJob.task2();}}}
TaskJob类
/*** 公共 定时任务 类** @author lijun* @date 2021/11/25 9:34*/@Servicepublic class TaskJob {@ResourceCommonMapper commonMapper;public void task1(){//需要执行的业务List<Object> list = commonMapper.selectTask1();}public void task2(){//需要执行的业务List<Object> list = commonMapper.selectTask2();}}
手动设置时间并且启动任务
Map<String,Object> params= new HashMap<>(4);params.put("type","task1");//两分钟执行一次quartzManager.addJob("task1", MyJob.class,"0 */2 * * * ?",params);
自动启动任务
/*** 启动监听类** @author lijun* @date 2021/11/25 9:56*/@Slf4j@Componentpublic class StartListener implements ApplicationListener<ApplicationStartedEvent> {@Resourceprivate QuartzManager quartzManager;/*** 监听项目启动时运行定时任务** @param event the event to respond to*/@Overridepublic void onApplicationEvent(ApplicationStartedEvent event) {log.info("定时程序启动:"+ DateUtil.dateToString(new Date(), SystemConstant.TIME_PATTEN));synDepartData();synPersonData();}public void synDepartData(){Map<String,Object> params= new HashMap<>(4);params.put("type","task1");quartzManager.addJob("task1", MyJob.class,"0 0 18 * * ?",params);// quartzManager.addJob("synDepartData", MyJob.class,"0 */2 * * * ?",params);}public void synPersonData(){Map<String,Object> params= new HashMap<>(4);params.put("type","task2");quartzManager.addJob("task2", MyJob.class,"0 0 18 * * ?",params);// quartzManager.addJob("synPersonData", MyJob.class,"0 */2 * * * ?",params);}}
