Quatz Spring for Dynamic Timing Tasks

Posted by chiprivers on Sun, 30 Jun 2019 20:05:55 +0200

Original address: http://blog.csdn.net/lll511521/article/details/99877

Reference address:

http://blog.csdn.net/gebitan505/article/details/45095105

https://www.dexcoder.com/selfly/article/297

https://www.dexcoder.com/selfly/article/308

http://www.cnblogs.com/super-admin/p/6481406.html?utm_source=itdadao&utm_medium=referral

http://blog.csdn.net/yangrunkangbla/article/details/51473169

http://www.cnblogs.com/xrab/p/5850186.html

Timing tasks are often used in practical project applications and can be accomplished by simple configurations of quartz and spring. However, if you want to change the execution time and frequency of tasks, abandon tasks, etc., you need to change the configuration or even restart the server. Here's how to dynamically change the status of a timed task through a combination of quartz and spring.

Reference article: http://www.meiriyouke.net/?p=82

This article is intended for readers who have a good understanding of quartz and spring.
Spring version 3.2 quartz version 2.2.1 If quartz 2.2.1 is used, spring version needs more than 3.1
1.
Introduction of registered bean s in spring

<bean id="schedulerFactoryBean"
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />

Why should I combine with spring?
In conjunction with spring, you can use spring to unify the lifecycle of tasks in quartz so that all tasks are closed together when the web container is closed.If you do not use spring management, you may see web containers closing and tasks still running. If you do not use spring, you can control the closing of tasks together when containers are closing.
2. Create entity classes that hold planned task information

/** 
 *  
* @Description: Scheduled Task Information
* @author snailxr 
* @date 2014 April 24, 2000 10:49:43 p.m.
 */  
public class ScheduleJob {  
   
    public static final String STATUS_RUNNING = "1";  
    public static final String STATUS_NOT_RUNNING = "0";  
    public static final String CONCURRENT_IS = "1";  
    public static final String CONCURRENT_NOT = "0";  
    private Long jobId;  
   
    private Date createTime;  
   
    private Date updateTime;  
    /** 
     * Task Name
     */  
    private String jobName;  
    /** 
     * Task Grouping
     */  
    private String jobGroup;  
    /** 
     * Task Status Whether to Start a Task
     */  
    private String jobStatus;  
    /** 
     * cron Expression
     */  
    private String cronExpression;  
    /** 
     * Description
     */  
    private String description;  
    /** 
     * Which class's method is called on task execution: package name + class name
     */  
    private String beanClass;  
    /** 
     * Is the task in a state?
     */  
    private String isConcurrent;  
    /** 
     * spring bean 
     */  
    private String springId;  
    /** 
     * Method name for task invocation
     */  
    private String methodName;  
   
    //get  set.......  
}

This entity class corresponds to tables in the database and stores multiple scheduled tasks in the database.

Note: jobName and groupName combinations should be unique, beanClass springId should have at least one

 

Run the following code at project startup:

public void init() throws Exception {
 
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
 
        //Get task information data from database here
        List<ScheduleJob> jobList = scheduleJobMapper.getAll();
     
        for (ScheduleJob job : jobList) {
            addJob(job);
        }
    }
/**
     * Add Task
     
     * @param scheduleJob
     * @throws SchedulerException
     */
    public void addJob(ScheduleJob job) throws SchedulerException {
        if (job == null || !ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())) {
            return;
        }
 
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        log.debug(scheduler + ".......................................................................................add");
        TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
 
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
 
        //Does not exist, create one
        if (null == trigger) {
            Class clazz = ScheduleJob.CONCURRENT_IS.equals(job.getIsConcurrent()) ? QuartzJobFactory.class : QuartzJobFactoryDisallowConcurrentExecution.class;
 
            JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup()).build();
 
            jobDetail.getJobDataMap().put("scheduleJob", job);
 
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
 
            trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
 
            scheduler.scheduleJob(jobDetail, trigger);
        else {
            //Trigger already exists, then update the corresponding timer settings
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
 
            //Rebuild trigger with new cronExpression expression
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
 
            //Reset job execution by new trigger
            scheduler.rescheduleJob(triggerKey, trigger);
        }
    }

See line 20 of the code to determine if the task is in state based on CONCURRENT_IS in the scheduleJob class.To give different Job implementation classes

/**
 
 * @Description: If a method does not complete the next rotation at one time, wait for the method change to complete before performing the next operation
 * @author snailxr
 * @date 2014 April 24, 2000 5:05:47 p.m.
 */
@DisallowConcurrentExecution
public class QuartzJobFactoryDisallowConcurrentExecution implements Job {
    public final Logger log = Logger.getLogger(this.getClass());
 
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
        TaskUtils.invokMethod(scheduleJob);
 
    }
}
/**
 
 * @Description: Scheduled Task Execution Office Stateless
 * @author snailxr
 * @date 2014 April 24, 2000 5:05:47 p.m.
 */
public class QuartzJobFactory implements Job {
    public final Logger log = Logger.getLogger(this.getClass());
 
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
        TaskUtils.invokMethod(scheduleJob);
    }
}

The code to actually perform the scheduled task is in TaskUtils.invokMethod(scheduleJob)

beanClass or springId of scheduleJob obtains the class to be executed by reflection or spring, and methodName determines which method to execute

public class TaskUtils {
    public final static Logger log = Logger.getLogger(TaskUtils.class);
 
    /**
     * Call methods defined in scheduleJob through reflection
     
     * @param scheduleJob
     */
    public static void invokMethod(ScheduleJob scheduleJob) {
        Object object = null;
        Class clazz = null;
                //SpringId is not empty Press springId to find bean s first
        if (StringUtils.isNotBlank(scheduleJob.getSpringId())) {
            object = SpringUtils.getBean(scheduleJob.getSpringId());
        else if (StringUtils.isNotBlank(scheduleJob.getBeanClass())) {
            try {
                clazz = Class.forName(scheduleJob.getBeanClass());
                object = clazz.newInstance();
            catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
 
        }
        if (object == null) {
            log.error("Task Name = [" + scheduleJob.getJobName() + "]---------------Not started successfully, please check if the configuration is correct!!!");
            return;
        }
        clazz = object.getClass();
        Method method = null;
        try {
            method = clazz.getDeclaredMethod(scheduleJob.getMethodName());
        catch (NoSuchMethodException e) {
            log.error("Task Name = [" + scheduleJob.getJobName() + "]---------------Failed to start successfully, method name set incorrectly!!!");
        catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (method != null) {
            try {
                method.invoke(object);
            catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
         
    }
}

Pause, delete, modify tasks, etc.

**
     * Get a list of all scheduled tasks
     
     * @return
     * @throws SchedulerException
     */
    public List<ScheduleJob> getAllJob() throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
        List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
        for (JobKey jobKey : jobKeys) {
            List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
            for (Trigger trigger : triggers) {
                ScheduleJob job = new ScheduleJob();
                job.setJobName(jobKey.getName());
                job.setJobGroup(jobKey.getGroup());
                job.setDescription("trigger:" + trigger.getKey());
                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                job.setJobStatus(triggerState.name());
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    job.setCronExpression(cronExpression);
                }
                jobList.add(job);
            }
        }
        return jobList;
    }
 
    /**
     * All running job s
     
     * @return
     * @throws SchedulerException
     */
    public List<ScheduleJob> getRunningJob() throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
        List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size());
        for (JobExecutionContext executingJob : executingJobs) {
            ScheduleJob job = new ScheduleJob();
            JobDetail jobDetail = executingJob.getJobDetail();
            JobKey jobKey = jobDetail.getKey();
            Trigger trigger = executingJob.getTrigger();
            job.setJobName(jobKey.getName());
            job.setJobGroup(jobKey.getGroup());
            job.setDescription("trigger:" + trigger.getKey());
            Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
            job.setJobStatus(triggerState.name());
            if (trigger instanceof CronTrigger) {
                CronTrigger cronTrigger = (CronTrigger) trigger;
                String cronExpression = cronTrigger.getCronExpression();
                job.setCronExpression(cronExpression);
            }
            jobList.add(job);
        }
        return jobList;
    }
 
    /**
     * Pause a job
     
     * @param scheduleJob
     * @throws SchedulerException
     */
    public void pauseJob(ScheduleJob scheduleJob) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
        scheduler.pauseJob(jobKey);
    }
 
    /**
     * Restore a job
     
     * @param scheduleJob
     * @throws SchedulerException
     */
    public void resumeJob(ScheduleJob scheduleJob) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
        scheduler.resumeJob(jobKey);
    }
 
    /**
     * Delete a job
     
     * @param scheduleJob
     * @throws SchedulerException
     */
    public void deleteJob(ScheduleJob scheduleJob) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
        scheduler.deleteJob(jobKey);
 
    }
 
    /**
     * Execute job immediately
     
     * @param scheduleJob
     * @throws SchedulerException
     */
    public void runAJobNow(ScheduleJob scheduleJob) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
        scheduler.triggerJob(jobKey);
    }
 
    /**
     * Update job Time Expression
     
     * @param scheduleJob
     * @throws SchedulerException
     */
    public void updateJobCron(ScheduleJob scheduleJob) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
 
        TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
 
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
 
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
 
        trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
 
        scheduler.rescheduleJob(triggerKey, trigger);
    }

Tips

Update the expression to determine if it is correct to use the code

CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("xxxxx");

The expression is incorrect if an exception is thrown

quartz-spring_demo.rar

Or you can get it on github

https://github.com/snailxr/quartz-spring_demo 


3 Comments so far | more »
This entry is published in 16 September 2014 .belong to java Categories, pasted java,quartz,spring Label.




Topics: Spring Database github Java