Maven依赖:
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency>
Quertz数据表(MySQL):
CREATE TABLE `sys_task` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `job_name` varchar(255) DEFAULT NULL COMMENT '任务名', `description` varchar(255) DEFAULT NULL COMMENT '任务描述', `cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron表达式', `bean_class` varchar(255) DEFAULT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名', `job_status` varchar(255) DEFAULT NULL COMMENT '任务状态',0:停止1:运行, `job_group` varchar(255) DEFAULT NULL COMMENT '任务分组', `create_user` varchar(64) DEFAULT NULL COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_user` varchar(64) DEFAULT NULL COMMENT '更新者', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;
INSERT INTO `sys_task` VALUES ('1', 'QuertzTask1', 'Quertz定时器测试一', '0/10 * * * * ?', 'com.example.demo.Quertz.TestQuertzTask', '1', 'group', null, null, null, null);
Quertz配置:
package com.example.demo.Quertz; import org.quartz.Scheduler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import java.io.IOException; import java.util.Properties; @Configuration public class QuartzConfigration { @Autowired private JobFactory jobFactory; @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); try { schedulerFactoryBean.setOverwriteExistingJobs(true); schedulerFactoryBean.setQuartzProperties(quartzProperties()); schedulerFactoryBean.setJobFactory(jobFactory); } catch (Exception e) { e.printStackTrace(); } return schedulerFactoryBean; } // 指定quartz.properties,可在配置文件中配置相关属性 @Bean public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/config/quartz.properties")); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } // 创建schedule @Bean(name = "scheduler") public Scheduler scheduler() { return schedulerFactoryBean().getScheduler(); } }
package com.example.demo.Quertz; import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.scheduling.quartz.AdaptableJobFactory; import org.springframework.stereotype.Component; @Component public class JobFactory extends AdaptableJobFactory { //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴. //为什么需要这个类呢,在我写的这个demo中,大家可以将此类删掉,发现程序也可以政策运营,可是我为什么还是加上呢。 //大家可以看下我们的任务类,大家可以看到Job对象的实例化过程是在Quartz中进行的,这时候我们将spring的东西注入进来,肯定是行不通的,所以需要这个类 @Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { //调用父类的方法 Object jobInstance = super.createJobInstance(bundle); //进行注入 capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }
SpringBoot启动加载定时器任务(实现接口 CommandLineRunner 来实现):
package com.example.demo.Quertz; import com.example.demo.Entity.Task; import com.example.demo.Service.QuertzTaskService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.util.List; @Component @Order(value = 1) public class QuartzTask implements CommandLineRunner { @Autowired private QuertzTaskService quertzTaskService; @Autowired private QuertzManage quertzManage; @Override public void run(String... arg0) throws Exception { List<Task> taskList = quertzTaskService.queryQuertzTask(); for (Task task : taskList) { quertzManage.addJob(task); } } }
Quertz定时器启动,暂停,运行等封装:
package com.example.demo.Quertz; import com.example.demo.Entity.Task; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class QuertzManage { @Autowired private Scheduler scheduler; /** * 添加一个job * @param task */ public void addJob(Task task) { try { // 创建jobDetail实例,绑定Job实现类 // 指明job的名称,所在组的名称,以及绑定job类 Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(task.getBeanClass()).newInstance() .getClass()); JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(task.getJobName(), task.getJobGroup())// 任务名称和组构成任务key .build(); // 定义调度触发规则 // 使用cornTrigger规则 Trigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(), task.getJobGroup())// 触发器key .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND)) .withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).startNow().build(); // 把作业和触发器注册到任务调度中 scheduler.scheduleJob(jobDetail, trigger); // 启动 if (!scheduler.isShutdown()) { scheduler.start(); } } catch (Exception e) { e.printStackTrace(); } } /** * 暂停一个job * @param jobName * @param jobGroup * @throws SchedulerException */ public void pauseJob(String jobName,String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); scheduler.pauseJob(jobKey); } /** * 恢复一个job * @param jobName * @param jobGroup * @throws SchedulerException */ public void resumeJob(String jobName,String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); scheduler.resumeJob(jobKey); } /** * 立即执行一个job * @param jobName * @param jobGroup * @throws SchedulerException */ public void runJobNow(String jobName,String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); scheduler.triggerJob(jobKey); } }
SpringDataJPA查询接口:
package com.example.demo.Service; import com.example.demo.Entity.Task; import org.quartz.SchedulerException; import java.util.List; public interface QuertzTaskService { List<Task> queryQuertzTask(); void pauseTaskById(String id) throws SchedulerException; void resumeTaskById(String id) throws SchedulerException; }
接口实现方法:
package com.example.demo.Service.Impl; import com.example.demo.Entity.Task; import com.example.demo.Quertz.QuertzManage; import com.example.demo.Repository.TaskRepository; import com.example.demo.Service.QuertzTaskService; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class QuertzTaskServiceImpl implements QuertzTaskService { @Autowired private TaskRepository taskRepository; @Autowired private QuertzManage quertzManage; @Override public List<Task> queryQuertzTask() { return taskRepository.findByJobStatus(); } @Override public void pauseTaskById(String id) throws SchedulerException { Optional<Task> task = taskRepository.findById(id); quertzManage.pauseJob(task.get().getJobName(),task.get().getJobGroup()); } @Override public void resumeTaskById(String id) throws SchedulerException { Optional<Task> task = taskRepository.findById(id); quertzManage.resumeJob(task.get().getJobName(),task.get().getJobGroup()); } }
定时任务:
package com.example.demo.Quertz; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; @DisallowConcurrentExecution //作业不并发 @Component public class TestQuertzTask implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Quertz定时器: "+dateFormat.format(new Date())); } }
源码:https://github.com/zeng-xian-guo/springboot_jwt_token.git
参考:https://blog.csdn.net/qq_40065776/article/details/107489728