定時任務任務的三種方法


1,spring整合quartz方式,這種網上資料太多,簡單引用一下就ok。

<bean id="taskJob" class="com.tyyd.dw.task.DataConversionTask"/>
        <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <property name="group" value="job_work"/>
            <property name="name" value="job_work_name"/>
            <!--false表示等上一個任務執行完后再開啟新的任務-->
            <property name="concurrent" value="false"/>
            <property name="targetObject">
                <ref bean="taskJob"/>
            </property>
            <property name="targetMethod">
                <value>run</value>
            </property>
        </bean>
        <!--  調度觸發器 -->
        <bean id="myTrigger"
              class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
            <property name="name" value="work_default_name"/>
            <property name="group" value="work_default"/>
            <property name="jobDetail">
                <ref bean="jobDetail" />
            </property>
            <property name="cronExpression">
                <value>0/5 * * * * ?</value>
            </property>
        </bean>
        <!-- 調度工廠 -->
        <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="myTrigger"/>
                </list>
            </property>
        </bean>

2.spring task方式的定時任務(最為簡單,功能也簡單)

<!-- 定時器配置  開始-->
    <bean id="task1" class="com.XXX.Task1"></bean>
       <bean id="task2" class="com.XXX.Task2"></bean>
       <task:scheduled-tasks>   
           <task:scheduled ref="task1" method="execute" cron="0 */1 * * * ?"/>
           <task:scheduled ref="task2" method="execute" cron="0 */1 * * * ?"/>    
    </task:scheduled-tasks>  
    <!-- 定時器配置  結束-->

使用的時候,直接寫一個類,一個方法就可以了,簡單快捷。task1類添加方法:

public void execute(){
 // TODO: 你的業務邏輯 
}

 3.使用quartz方式,可以動態修改任務執行時間和參數的工具方法。

import java.util.List;
import java.util.Set;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.DirectSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 參考
 * http://blog.csdn.net/xlxxcc/article/details/52115995
 * @ClassName: QuartzManager 
 * @author lishang
 * @Description quartz定時任務管理增刪改
 * @date 2017年11月2日 下午1:27:47 
 *
 */
public class QuartzManager {

    protected static final Logger LOG = LoggerFactory.getLogger(QuartzManager.class);
    //private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
    private static DirectSchedulerFactory schedulerFactory=DirectSchedulerFactory.getInstance();
    static{
        try {
            schedulerFactory.createVolatileScheduler(3);
        } catch (SchedulerException e) {
            LOG.info("創建DirectSchedulerFactory的Scheduler失敗!",e);
        }
    }
    /**
     * 判斷一個job是否存在
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     * @return
     */
    public static boolean isExistJob(String jobName, String jobGroupName){
        boolean exist=false;
        try {
            
            Scheduler sched = schedulerFactory.getScheduler();
            JobKey jobKey = new JobKey(jobName, jobGroupName);
            exist = sched.checkExists(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }  
        return exist;
        
    }
    /** 
     * @Description: 添加一個定時任務 
     *  
     * @param jobName 任務名 
     * @param jobGroupName  任務組名 
     * @param triggerName 觸發器名 
     * @param triggerGroupName 觸發器組名 
     * @param jobClass  任務 
     * @param cron   時間設置,參考quartz說明文檔  
     */  
    @SuppressWarnings("unchecked")
    public static void addJob(String jobName, String jobGroupName, 
            String triggerName, String triggerGroupName, Class jobClass,JobDataMap jMap, String cron) {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            // 任務名,任務組,任務執行類
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
                    .usingJobData(jMap).build();

            // 觸發器  
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 觸發器名,觸發器組  
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();
            // 觸發器時間設定  
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 創建Trigger對象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();

            // 調度容器設置JobDetail和Trigger
            sched.scheduleJob(jobDetail, trigger);  
            Trigger.TriggerState triggerState = sched.getTriggerState(trigger.getKey());
            LOG.info("job的觸發器狀態:"+triggerState.name());
            System.out.println("job的觸發器狀態:"+triggerState.name());
            // 啟動  
            if (!sched.isShutdown()) {  
                sched.start();  
            }
            //按新的trigger重新設置job執行
            sched.rescheduleJob(trigger.getKey(), trigger);
        } catch (Exception e) { 
            LOG.error("添加一個定時任務發生異常:",e);
            throw new RuntimeException(e);  
        }  
    }  

    /** 
     * @Description: 修改一個任務的觸發時間
     *  
     * @param jobName 
     * @param jobGroupName
     * @param triggerName 觸發器名
     * @param triggerGroupName 觸發器組名 
     * @param cron   時間設置,參考quartz說明文檔   
     */  
    public static void modifyJobTime(String jobName, 
            String jobGroupName, String triggerName, String triggerGroupName,@SuppressWarnings("rawtypes") Class jobClass,JobDataMap jMap,String cron) {  
                /** 方式一 :調用 rescheduleJob 開始 */
                // 觸發器  
                //TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 觸發器名,觸發器組  
                //triggerBuilder.withIdentity(triggerName, triggerGroupName);
                //triggerBuilder.startNow();
                // 觸發器時間設定  
                //triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 創建Trigger對象
                //trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 :修改一個任務的觸發時間
                //sched.rescheduleJob(triggerKey, trigger);
                /** 方式一 :調用 rescheduleJob 結束 */

                /** 方式二:先刪除,然后在創建一個新的Job  */
                removeJob(jobName, jobGroupName, triggerName, triggerGroupName);  
                addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, jMap, cron);
                /** 方式二 :先刪除,然后在創建一個新的Job */
    }  

    /** 
     * @Description: 移除一個任務 
     *  
     * @param jobName 
     * @param jobGroupName 
     * @param triggerName 
     * @param triggerGroupName 
     */  
    public static void removeJob(String jobName, String jobGroupName,  
            String triggerName, String triggerGroupName) {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  

            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);

            sched.pauseTrigger(triggerKey);// 停止觸發器  
            sched.unscheduleJob(triggerKey);// 移除觸發器  
            sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 刪除任務  
            
            List<String> jobGroupNames = sched.getJobGroupNames();
            LOG.info("任務組開始-->groupsNames=[");
            for (String string : jobGroupNames) {
                GroupMatcher<JobKey> matcher=GroupMatcher.jobGroupEquals(string);
                Set<JobKey> jobKeys = sched.getJobKeys(matcher);
                LOG.info(string+"下的JOB為[");
                for (JobKey jobKey : jobKeys) {
                    LOG.info(jobKey.getName()+",");
                }
                LOG.info("]");
                
            }
            LOG.info("]任務組結束。");
        } catch (Exception e) {  
            LOG.error("移除job任務發生異常:",e);
            throw new RuntimeException(e);  
        }  
    }  

    /** 
     * @Description:啟動所有定時任務 
     */  
    public static void startJobs() {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            sched.start();  
        } catch (Exception e) {  
            LOG.error("啟動所有定時任務發生異常:",e);
            throw new RuntimeException(e);  
        }  
    }  

    /** 
     * @Description:關閉所有定時任務 
     */  
    public static void shutdownJobs() {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            if (!sched.isShutdown()) {  
                sched.shutdown();  
            }  
        } catch (Exception e) {  
            LOG.error("關閉所有定時任務發生異常:",e);
            throw new RuntimeException(e);  
        }  
    }  
}

之前項目中使用的調度工廠類是:StdSchedulerFactory 然后定時任務動態修改的時候總是不穩定。后來改為上面的工廠類,問題得到了解決。

原因是其他地方有使用StdSchedulerFactory 的調度器,所有的調度任務都會在這個工廠中,不容易控制,而DirectSchedulerFactory這個工廠是每個new生成一個實例,更容易控制。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.使用quartz方式,不整合spring


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM