代码&优雅着&生活

导航

定时任务任务的三种方法

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

posted on 2017-11-14 19:58  幸运的凌人  阅读(7714)  评论(0编辑  收藏  举报