Spring boot uses quartz to dynamically add tasks

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/{id}")
    public String add(@PathVariable("id") Integer id) throws SchedulerException {

        myScheduler.add(id);

        return "success";
    }

    @RequestMapping("/del/{id}")
    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

 

Published 10 original articles, won praise 1, visited 5797
Private letter follow

Tags: Spring Database Lombok Mybatis

Posted on Mon, 13 Jan 2020 10:55:34 -0500 by csplrj