In the project, the page needs to dynamically add timed tasks and delete tasks.
The practice of others is used for reference. Now the design method is recorded as follows:
1. Spring boot project directly depends on
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
2. Add @ EnableScheduling to the startup class
3. Add quartz configuration file quartz.properties
org.quartz.scheduler.instanceName = MyScheduler org.quartz.scheduler.instanceId = AUTO org.quartz.scheduler.rmi.export = false org.quartz.scheduler.rmi.proxy = false org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
4. Configuration class
@Configuration @Slf4j public class QuartzThreadPoolConfig { @Autowired private ThreadPoolTaskExecutor threadPoolTaskExecutor; @Bean @Order(2) public SchedulerFactoryBean getSchedulerFactoryBean() throws IOException { if(threadPoolTaskExecutor == null){ log.error("threadPoolTaskExecutor is null"); System.exit(0); } PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/config/quartz.properties")); //The properties in quartz.properties are read and injected before the object is initialized propertiesFactoryBean.afterPropertiesSet(); //Create SchedulerFactoryBean SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setTaskExecutor(threadPoolTaskExecutor); factory.setQuartzProperties(propertiesFactoryBean.getObject()); //In this way, when spring is shut down, it will wait for all started quartz job s to finish before spring can completely shut down. factory.setWaitForJobsToCompleteOnShutdown(true); factory.setOverwriteExistingJobs(false); factory.setStartupDelay(1); return factory; } @Bean("taskExecutor") @Primary @Order(1) public ThreadPoolTaskExecutor getThreadPoolTaskExecutor(){ ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); threadPoolTaskExecutor.setMaxPoolSize(5); threadPoolTaskExecutor.setCorePoolSize(2); RejectedExecutionHandler handler = new RejectedExecutionHandler() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { log.error("Thread pool exceeds maximum capacity,Capacity expansion {} ",executor.getPoolSize()); executor.setMaximumPoolSize(10); Thread thread = new Thread(r); thread.start(); log.error(r.toString()); } }; threadPoolTaskExecutor.setRejectedExecutionHandler(handler); return threadPoolTaskExecutor; } }
5. Listener, project start to load tasks to be executed from database
@Component public class QuartzInitLisenter implements ApplicationListener<ContextRefreshedEvent>{ @Resource private SchedulerAllJob schedulerAllJob; @Override public void onApplicationEvent(ContextRefreshedEvent event) { try { schedulerAllJob.scheduleJobs(); } catch (SchedulerException e) { e.printStackTrace(); } System.out.println("ssssss>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); } }
6. Add and delete tasks
@Component public class SchedulerAllJob { @Resource private SchedulerFactoryBean schedulerFactoryBean; @Resource private QuartzMapper quartzMapper; /* * Here, you can inject database operations to query all task configurations */ /** * This method is used to start all scheduled tasks * @throws SchedulerException */ public void scheduleJobs() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); scheduleJob1(scheduler); } public void stop() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); scheduler.clear(); } public void remove(int i) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); boolean deleteJob = scheduler.deleteJob(new JobKey("job" + i, "group1")); System.out.println(deleteJob); } public void add(int i) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class) .withIdentity("job" + i, "group1").build(); // Once every 5s CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("*/5 * * * * ?"); CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job" + i, "group1") .withSchedule(scheduleBuilder).build(); cronTrigger.getJobDataMap().put("taskId",i); scheduler.scheduleJob(jobDetail,cronTrigger); } /** * Configure Job1 * The tasks here can be configured to be placed in properties or database * @param scheduler * @throws SchedulerException */ private void scheduleJob1(Scheduler scheduler) throws SchedulerException{ Wrapper<QuartzTask> wrapper = new EntityWrapper<>(); List<QuartzTask> tasks = quartzMapper.selectList(wrapper); if(tasks != null && !tasks.isEmpty()){ for (QuartzTask task : tasks) { JobKey jobKey = new JobKey(task.getJobName(), task.getJobGroup()); JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class) .withIdentity(jobKey).build(); CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getQuartzTime()); CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(), task.getJobGroup()) .withSchedule(scheduleBuilder).build(); cronTrigger.getJobDataMap().put("taskId", task.getId()); if (!scheduler.checkExists(jobKey)) { scheduler.scheduleJob(jobDetail,cronTrigger); } } } } }
7. Business execution
@Slf4j public class ScheduledJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { log.info("schedule job1 is running {} {}",jobExecutionContext.getTrigger().getJobDataMap().get("taskId"),jobExecutionContext.getJobInstance().toString()); //Get response information from database according to taskId and execute //todo business code } }
8. Simple task controller
@RestController @RequestMapping("/quartz") public class QuartzController { @Autowired public SchedulerAllJob myScheduler; @RequestMapping("/start") public String schedule() throws SchedulerException { myScheduler.scheduleJobs(); return "success"; } @RequestMapping("/stop") public String stop() throws SchedulerException { myScheduler.stop(); return "success"; } @RequestMapping("/add/") public String add(@PathVariable("id") Integer id) throws SchedulerException { myScheduler.add(id); return "success"; } @RequestMapping("/del/") public String del(@PathVariable("id") Integer id) throws SchedulerException { myScheduler.remove(id); return "success"; } }
9. Entity class and Mapper
@lombok.Data public class QuartzTask { private Long id; private String type; private String jobGroup; private String jobName; private String invokeParam; private String quartzTime; private String status; private Date executeEndtime; }
@Mapper public interface QuartzMapper extends BaseMapper<QuartzTask> { //Using mybatis plus }
The above is the function test demo
reference material:
1,https://blog.csdn.net/zhaoyahui_666/article/details/78835128
2,https://blog.csdn.net/fanghuainihao/article/details/95462526
frwcode Published 10 original articles, won praise 1, visited 5797 Private letter follow