Quartz快速入门

一、Quartz简介

1.quartz是开源且具有丰富特性的"任务调度库",能够集成于任何的java应用。

2.quartz主要分为三大组件,分别是任务Job、触发器Trigger以及调度器Scheduler。

quartz体系架构图:

 

二、quartz三大组件简介

1.任务Job:即想要调用的任务类,需要实现org.quartz.job接口,并重写execute()方法,任务调度时会执行execute()方法。

2.触发器Trigger:即执行任务的触发器,当满足什么条件时会去执行你的任务Job,主要分为根据时长间隔执行的SimpleTrigger和根据日历执行的CronTrigger。

3.调度器Scheduler:即将Trigger和Job绑定之后,根据Trigger中的设定,负责进行Job调度的组件。

其它:

    1.一个调度器可以让多个触发器Trigger和任务Job绑定,而一个任务Job实例只能和一个触发器Trigger实例绑定,反过来也是如此。

 

三、案例入门

1.引入maven:

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.3.2</version>
        </dependency>

本文使用的是2.3.2版本,建议使用最新版本,如果需要日志可自行引入。

2.测试代码:

public class QuartzTest {


    public static void main(String[] args) throws SchedulerException {
        //1.调度器(Scheduler)
        SchedulerFactory schedulerfactory = new StdSchedulerFactory();
        //拿到调度器,调度器只需要一个即可,可以调度多个任务
        Scheduler scheduler = schedulerfactory.getScheduler();
        //2.Job实例(JobDetil)
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                .withIdentity("job", "default") //name:任务的名称,group:分组名
                .build();
        //3.触发器(Trigger)
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger", "default") //name:触发器名称,group:分组名
                .startNow() //马上执行一次,默认
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(20,2))//使用Simple触发器,执行20次,间隔2秒
                .build();
        //4.让Job和触发器关联
        scheduler.scheduleJob(jobDetail,trigger);
        //5.进行任务调度
        scheduler.start();
    }

    
    public static class MyJob implements Job {
        
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            //打印当前时间
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = dateFormat.format(new Date());
            System.out.println(date);
        }
    }
}

3.执行结果:

    每两秒打印一次时间。

3.步骤说明:

通过上文,可以大概知道quartz的操作大概分为六步:

1.通过SchedulerFactory获取一个任务调度器Scheduler

2.实现org.quartz.job接口,并重写execute()方法为自己需要的任务调度逻辑。

3.通过JobBuilder.newJob()构建一个JobDetail(Job实例对象),并设置对应参数。

4.通过TriggerBuilder.newTrigger()构建一个触发器Trigger,并设置对应的参数。

5.通过Scheduler将JobDetail和Trigger绑定。

6.通过Scheduler的start()方法开始进行任务的调度。

 

四、参数传递

1.测试代码:

public class QuartzTest {


    public static void main(String[] args) throws SchedulerException{
        //1.调度器(Scheduler)
        SchedulerFactory schedulerfactory = new StdSchedulerFactory();
        //拿到调度器,调度器只需要一个即可,可以调度多个任务
        Scheduler scheduler = schedulerfactory.getScheduler();
        //2.Job实例(JobDetil)
        JobDataMap jobDetailMap = new JobDataMap();
        jobDetailMap.put("name","xuye");
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                .withIdentity("job", "default") //name:任务的名称,group:分组名
                .usingJobData(jobDetailMap) //传递参数
                .build();
        //3.触发器(Trigger)
        JobDataMap triggerMap = new JobDataMap();
        triggerMap.put("age",100);
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger", "default") //name:触发器名称,group:分组名
                .usingJobData(triggerMap)
                .startNow() //马上执行一次,默认
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(1,2))//使用Simple触发器,执行1次,间隔2秒
                .build();
        //4.让调度器关联Job和触发器
        scheduler.scheduleJob(jobDetail,trigger);
        scheduler.start();
    }

    public static class MyJob implements Job {



        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            //方式一,获取JobDetail和Trigger传递的所有参数信息,使用此方式则不能对其进行设值。
            JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap();
            //方式二,获取JobDetail的Map参数
            JobDataMap jobDetailMap = jobExecutionContext.getJobDetail().getJobDataMap();
            //方式三,获取Trigger的Map参数
            JobDataMap triggerMap = jobExecutionContext.getTrigger().getJobDataMap();
            System.out.println("getMergedJobDataMap()方法中能获取到的key和value:\n"+getKeyAndValue(jobDataMap));
            System.out.println("getJobDetail().getJobDataMap()方法中能获取到的key和value:\n"+getKeyAndValue(jobDetailMap));
            System.out.println("getTrigger().getJobDataMap()方法中能获取到的key和value:\n"+getKeyAndValue(triggerMap));
        }

        private String getKeyAndValue(Map<String,Object> map) {
            StringBuilder sb = new StringBuilder();
            Set<Map.Entry<String, Object>> entries = map.entrySet();
            for(Map.Entry<String, Object> entry : entries) {
                sb.append(entry.getKey()+":"+entry.getValue().toString()+",");
            }
            return sb.toString();
        }
    }
}

2.执行结果:

3.说明:

    1.通过使用 JobDataMap对象,在JobBuilder和TriggerBuilder中调用usingJobData方法将JobDataMap设置进去。

    2.在org.quartz.job实现类中通过JobExecutionContext上文下环境获取对应的参数,主要有以下3个方法,

        1)jobExecutionContext.getMergedJobDataMap():

             获取JobBuilder和TriggerBuilder中两个的Map参数,注意使用该方式只能获取值,不能设置值,因为是无效的。

        2)jobExecutionContext.getJobDetail().getJobDataMap():

             获取JobDetail的Map参数,只能获取JobDetail的。

        3)jobExecutionContext.getTrigger().getJobDataMap():

             获取Trigger的Map参数,只能获取Trigger的。

    3.建议:如果只获取值,则使用jobExecutionContext.getMergedJobDataMap(),如果需要获取值,并把值传递到下一个任务调度中,请使用JobDetail或Trigger的对应参数。

    4.jobExecutionContext.getMergedJobDataMap()不能设置原理说明:每次任务调度时,都会创建一个JobExecutionContext,而创建后会把JobDetail或Trigger的对应参数全部设置到一个新的Map中,如果进行设值,则下次创建的还是新创建一个Map,上一个JobExecutionContext的设值则变为无效。

 

五、JobDataMap持久化

1.测试代码:

public class QuartzTest {

    public static void main(String[] args) throws SchedulerException{
        //1.调度器(Scheduler)
        SchedulerFactory schedulerfactory = new StdSchedulerFactory();
        //拿到调度器,调度器只需要一个即可,可以调度多个任务
        Scheduler scheduler = schedulerfactory.getScheduler();
        //2.Job实例(JobDetil)
        JobDataMap jobDetailMap = new JobDataMap();
        jobDetailMap.put("count",0);
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                .withIdentity("job", "default") //name:任务的名称,group:分组名
                .usingJobData(jobDetailMap) //传递参数
                .build();
        //3.触发器(Trigger)
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger", "default") //name:触发器名称,group:分组名
                .startNow() //马上执行一次,默认
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(20,2))//使用Simple触发器,执行20次,间隔2秒
                .build();
        //4.让调度器关联Job和触发器
        scheduler.scheduleJob(jobDetail,trigger);
        scheduler.start();
    }

    public static class MyJob implements Job {
        
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            //获取JobDetail的Map参数
            JobDataMap jobDetailMap = jobExecutionContext.getJobDetail().getJobDataMap();
            Integer count = (Integer) jobDetailMap.get("count");
            ++count;
            System.out.println("当前执行次数:"+count);
            jobDetailMap.put("count",count);
        }

    }
}

2.执行结果:

3.说明:

    1.我们想要统计执行次数,但每次获取到的JobDetail参数Map都是新的。

    2.如果想要JobDetail和Trigger的Map参数都是持久化,只需要在该Job实例的类上加上注@PersistJobDataAfterExecution即可。

    3.修改如下:

    4.新的测试结果:

    5.JobDetail和Trigger的效果一致,Trigger代码就不多写,如果使用jobExecutionContext.getMergedJobDataMap(),只能获取JobDetail和Trigger的Map数据,并不能设值,上文已经说明原理,可自行测试。

 

六、自动注入

1.测试代码:

public class QuartzTest {

    public static void main(String[] args) throws SchedulerException{
        //1.调度器(Scheduler)
        SchedulerFactory schedulerfactory = new StdSchedulerFactory();
        //拿到调度器,调度器只需要一个即可,可以调度多个任务
        Scheduler scheduler = schedulerfactory.getScheduler();
        //2.Job实例(JobDetil)
        JobDataMap jobDetailMap = new JobDataMap();
        jobDetailMap.put("name","xuye");
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                .withIdentity("job", "default") //name:任务的名称,group:分组名
                .usingJobData(jobDetailMap) //传递参数
                .build();
        //3.触发器(Trigger)
        JobDataMap triggerMap = new JobDataMap();
        triggerMap.put("age",100);
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger", "default") //name:触发器名称,group:分组名
                .usingJobData(triggerMap)
                .startNow() //马上执行一次,默认
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(1,2))//使用Simple触发器,执行1次,间隔2秒
                .build();
        //4.让调度器关联Job和触发器
        scheduler.scheduleJob(jobDetail,trigger);
        scheduler.start();
    }
    
    public static class MyJob implements Job {

        private String name;
        
        private Integer age;

        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            System.out.println("name:"+name+",age:"+age);
        }

        public void setName(String name) {
            this.name = name;
        }
        
        public void setAge(Integer age) {
            this.age = age;
        }
    }
}

2.执行结果:

  

3.说明:

     1.如需使用自动注入,只需要org.quartz.job实现类中提供和其对应的属性名的set方法即可。

 

七、常用API

1.StdSchedulerFactory

    

方法名说明
Scheduler getScheduler()
获取一个调度器
Scheduler
void initialize(Properties props)
初始化SchedulerFactory
Collection<Scheduler> getAllSchedulers()
获取所有的Scheduler

2.Scheduler

方法名说明
Date scheduleJob(JobDetail jobDetail, Trigger trigger)
将JobDetail和Trigger绑定
void triggerJob(JobKey jobKey)
通过JobKey立马执行一个Job
void triggerJob(JobKey jobKey, JobDataMap data)
通过JobKey立马执行一个Job,并传递参数
void start()
开始调度所有的任务,如果是暂停后调用则为重启
void shutdown()
马上关闭所有任务
void shutdown(boolean waitForJobsToComplete)
是否等待任务执行完关闭,true等待,false不等待
void standby()
暂停所有任务Job,通过start()方法重启
void pauseJob(JobKey jobKey)
通过JobKey暂停某个Job
void resumeJob(JobKey jobKey)
通过JobKey唤醒某个暂停的Job
void pauseTrigger(TriggerKey triggerKey)
暂停某个Trigger的所有Job
void resumeTrigger(TriggerKey triggerKey)
唤醒某个暂停的Trigger的Job

3.JobBuilder

方法名说明
JobBuilder newJob(Class <? extends Job> jobClass):静态方法
加载Job的实例
JobBuilder withIdentity(String name, String group)
设置该
JobDetail的名字和分组
JobBuilder usingJobData(String dataKey, String value)
传递参数,通过key和value
JobBuilder usingJobData(JobDataMap newJobDataMap)
传递参数,通过JobDataMap
JobDetail build()
按照之前的参数设置,构建一个JobDetail

 

4.JobDetail

方法名说明
JobDataMap getJobDataMap()
获取该JobDetail的JobDataMap
JobKey getKey()
获取该JobDetail的JobKey

 

5.TriggerBuilder

方法名说明
TriggerBuilder<Trigger> newTrigger:静态方法
加载一个Trigger
TriggerBuilder<T> withIdentity(String name, String group)
设置该
Trigger的名字和分组
TriggerBuilder<T> usingJobData(String dataKey, String value)
传递参数,通过key和value
TriggerBuilder<T> usingJobData(JobDataMap newJobDataMap)
传递参数,通过JobDataMap
TriggerBuilder<SBT> withSchedule(ScheduleBuilder<SBT> schedBuilder)
关联一个ScheduleBuilder,通常是SimpleScheduleBuilder或CronScheduleBuilder
T build()
按照之前的参数设置,构建一个Trigger

6.Trigger

方法名说明
JobDataMap getJobDataMap()
获取该JobDetail的JobDataMap
 Date getNextFireTime()
获取下一次执行时间
TriggerKey getKey()
获取该Trigger的TriggerKey
Date getEndTime()
获取结束时间
Date getStartTime()
获取开始时间

7.SimpleScheduleBuilder

方法名说明
SimpleScheduleBuilder repeatSecondlyForever(int seconds):静态方法

 

构建一个重复执行,按秒
SimpleScheduleBuilder repeatSecondlyForTotalCount(int count, int seconds):静态方法
重复执行,间隔按秒,并且执行一定的次数。
类似上面2个重复执行的静态方法还有按分钟,按小时,因为内容过多便不写出来,方法名都是类似的。
 
SimpleScheduleBuilder withRepeatCount(int triggerRepeatCount)
重复执行的次数,注意:如果是1,则执行2次,因为运行立马执行一次,以此类推。

8.CronScheduleBuilder

方法名说明
CronScheduleBuilder cronSchedule(String cronExpression):静态方法

 

根据cron表达式构建一个CronScheduleBuilder

 

9.CronExpression

方法名说明
boolean isValidExpression(String cronExpression):静态方法

 

校验Cron表达式
CronExpression(String cronExpression)
构造函数,检验一个Cron表达式,如果不通过则抛出异常,该异常信息包含不通过的原因

 

八、Cron表达式

Cron表达式被用来配置CronTrigger实例,Cron表达式是一个由7个子表达式(第7个可以省略)组成的字符串。一般格式如下:* * * * * ?或* * * * * ?*,每个子表达式的代表一个日期细节,具体如下:

位置说明允许值允许的特殊字符
1Seconds 秒0-59, / * -
2Minutes 分钟0-59, / * -
3Hours 小时0-23, / * -
4Day-of-Month 月中的天1-31, / * - ? L W C
5 Month 月1-12或英文JAN-DEC, / * -
6Day-of-Week 周中的天1-7或英文SUN-SAT, / * - ? L C #
7Year (optional field) 年(可选)1970-2099(一般不写), / * -

特殊字符含义说明:

字符含义
,(逗号)表示多个值,如秒中使用逗号分隔5,10,20,则表示在5秒、10秒、20秒执行,理解为或。
?表示不指定值,用于第四(月中的天)和第六位(周中的天),因为第四位和第六位是冲突的,如果第四位有值则第六位必须为?,反过来也是如此。
*表示所有可能的值,如果秒中使用*则表示60秒的每一秒都执行,小时上使用*则表示24小时的每个小时都执行。
-表示区间,如小时上用6-8,则表示6,7,8点都会执行。
/表示间隔,如在秒中使用0/20,则表示每隔20秒执行一次。
#表示月中的第几个周几,如6#3,表示该月第三周的周五(国外的周日=我们的周一)
W指定离给定日期最近的工作日(周一到周五)
L用在第四位(月中的天)表示一个月中的最后一天,用在第六位(周中的天)表示该月最后一个星期X,如用在第六位6L,则表示这个月的最后一个周五

九、Trigger触发器

Trigger触发器主要分为两大类:Simple触发器(通过SimpleScheduleBuilder关联)和Cron触发器(通过CronScheduleBuilder关联),上文案例中已经介绍了SimpleScheduleBuilder的使用和API设置,下面看CronScheduleBuilder的使用。

1.测试代码:

public class QuartzTest {


    public static void main(String[] args) throws SchedulerException{
        //1.调度器(Scheduler)
        SchedulerFactory schedulerfactory = new StdSchedulerFactory();
        //拿到调度器,调度器只需要一个即可,可以调度多个任务
        Scheduler scheduler = schedulerfactory.getScheduler();
        //2.Job实例(JobDetil)
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                .withIdentity("job", "default") //name:任务的名称,group:分组名
                .build();
        //3.触发器(Trigger)
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger", "default") //name:触发器名称,group:分组名
                .startNow() //马上执行一次
                .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))//使用Cron触发器
                .build();
        //4.让Job和触发器关联
        scheduler.scheduleJob(jobDetail,trigger);
        scheduler.start();
    }


    public static class MyJob implements Job {

        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            //打印当前时间
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = dateFormat.format(new Date());
            System.out.println(date);
        }
    }
}

2.执行结果:

    cron表达式为:0/3 * * * * ? 即从0秒开始,每间隔3秒执行一次。

 

十、StdSchedulerFactory的配置

上文中介绍了StdSchedulerFactory的API,其中就有一个initialize(Properties props)方法,对StdSchedulerFactory进行初始化,常用的配置的属性名和值如下:

属性名说明
org.quartz.threadPool.class使用哪个线程池(要实现org.quartz.spi.ThreadPool接口的线程池),一般用org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount 线程池线程数量,根据自己情况定,最好不要超过100
org.quartz.threadPool.threadPriority 线程优先级,1-10,数字越小优先级越高,一般用5即可。
org.quartz.scheduler.instanceName
调度器的名字
org.quartz.scheduler.instanceId
为调度器创建一个Key值,这个Key必须在所有调度器中唯一,一般填写AUTO,让quartz自动生成。
org.quartz.jobStore.class
任务调度存储(需要实现org.quartz.spi.JobStore接口的实例),一般用org.quartz.impl.jdbcjobstore.JobStoreTX

 

十一、工具类

上文大致把quartz基本内容概述完毕,下一篇博客将会进行高级内容概述,在此之前,先奉上本人自己写的一个quartz任务调度工具类,能够及其方便的根据间隔或corn表达式调度任意一个类的某个方法,代码如下:

public class SchedulerUtils {

    private static StdSchedulerFactory schedulerfactory = new StdSchedulerFactory();



    public static final int SECONDS = 1;

    public static final int MINUTES = 2;

    public static final int HOURS = 3;


    private static String CLASS_KEY = "CLASS-KEY";
    private static String METHOD_KEY = "METHOD-KEY";
    private static String PARAMS_KEY = "PARAMS-KEY";

    /**
     * 初始化StdSchedulerFactory
     * @param map 初始化参数
     * @throws SchedulerException
     */
    public static void init(Map<String,String> map) throws SchedulerException {
        Properties properties = new Properties();
        for(Map.Entry<String, String> entry : map.entrySet()) {
            properties.setProperty(entry.getKey(),entry.getValue());
        }
        init(properties);
    }

    public static void init(Properties properties) throws SchedulerException {
        schedulerfactory.initialize(properties);
    }

    /**
     *  按Cron表达式定时执行
     * @param clazzName 全类名
     * @param methodName 方法名
     * @param args 方法参数
     * @param cron cron表达式
     * @throws Exception
     */
    public static void executeJobCron(String clazzName, String methodName, List<Object> args,String cron) throws Exception {
        executeJobCron(clazzName,methodName,args,cron,null,null);
    }

    /**
     *  按Cron表达式定时执行
     * @param clazzName 全类名
     * @param methodName 方法名
     * @param args 方法参数
     * @param cron cron表达式
     * @param startDate 开始时间,如果马上开始填写null或 new Date()即可
     * @param endDate 结束时间,如果没有结束时间则填写null即可
     * @throws Exception
     */
    public static void executeJobCron(String clazzName, String methodName, List<Object> args,String cron,Date startDate,Date endDate) throws Exception {
        JobDetail jobDetail = jobDetailHandle(clazzName, methodName, args);
        Trigger trigger = cronTriggerTimeHandle(cron,startDate,endDate);
        Scheduler scheduler = getScheduler();
        scheduler.scheduleJob(jobDetail,trigger);
        scheduler.start();
    }


    public static void executeJob(String clazzName, String methodName, List<Object> args, int timeUnit, int interval, Date endDate) throws Exception{
        executeJob(clazzName,methodName,args,timeUnit,interval,-1,null,endDate);
    }


    public static void executeJob(String clazzName, String methodName, List<Object> args, int timeUnit, int interval)  throws Exception{
        executeJob(clazzName,methodName,args,timeUnit,interval,-1,null,null);
    }

    public static void executeJob(String clazzName, String methodName, List<Object> args, int timeUnit, int interval, int count)  throws Exception{
        executeJob(clazzName,methodName,args,timeUnit,interval,count,null,null);
    }


    /**
     *  按照间隔时间定时执行
     * @param clazzName 全类名
     * @param methodName 方法名
     * @param args 方法参数
     * @param timeUnit 时间单位,参考本类属性定义
     * @param interval 间隔长度
     * @param count 执行总数,如果执行总数和结束时间都有,则按结束时间。
     * @param startDate 开始时间,如果马上开始填写null或 new Date()即可
     * @param endDate 结束时间,如果没有结束时间则填写null即可
     * @throws Exception
     */
    public static void executeJob(String clazzName, String methodName, List<Object> args, int timeUnit, int interval, int count,Date startDate,Date endDate)  throws Exception {
        JobDetail jobDetail = jobDetailHandle(clazzName, methodName, args);
        Trigger trigger = simpleTriggerTimeHandle(timeUnit,interval, count,startDate,endDate);
        Scheduler scheduler = getScheduler();
        scheduler.scheduleJob(jobDetail,trigger);
        scheduler.start();
    }

    private static JobDetail jobDetailHandle(String clazzName, String methodName, List<Object> args) throws NoSuchMethodException, ClassNotFoundException {
        JobDataMap jobDataMap = new JobDataMap();
        Class clazz = Class.forName(clazzName);
        Method method = findMethod(clazz,methodName,args);
        jobDataMap.put(CLASS_KEY,clazz);
        jobDataMap.put(METHOD_KEY,method);
        jobDataMap.put(PARAMS_KEY,args);
        JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)
                .withIdentity("job")
                .usingJobData(jobDataMap)
                .build();
        return jobDetail;
    }

    private static Trigger simpleTriggerTimeHandle(int timeUnit, int interval, int count, Date startDate,Date emdDate) {
        TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger()
                .withIdentity("simpleTrigger");
        if(startDate == null) {
            startDate = new Date();
        }
        triggerBuilder.startAt(startDate);
        triggerBuilder.endAt(emdDate);
        if(count > 0) {
            switch (timeUnit) {
                case SECONDS : triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(count,interval));
                    break;
                case MINUTES : triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatMinutelyForTotalCount(count,interval));
                    break;
                case HOURS : triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatHourlyForTotalCount(count,interval));
                    break;
            }
        }
        return triggerBuilder.build();
    }

    private static Trigger cronTriggerTimeHandle(String cron,Date startDate,Date emdDate) throws ParseException {
        new CronExpression(cron);
        if(startDate == null) {
            startDate = new Date();
        }
        Trigger trigger =  TriggerBuilder.newTrigger()
                .withIdentity("cronTrigger")
                .startAt(startDate)
                .endAt(emdDate)
                .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                .build();
        return trigger;
    }

    private static Scheduler getScheduler() throws SchedulerException {
        return schedulerfactory.getScheduler();
    }

    private static Method findMethod(Class clazz,String methodName,List<Object> args) throws NoSuchMethodException {
        Method method;
        if(args != null && !args.isEmpty()) {
            Class<?>[] paramsTypes = getMethodParamsType(args);
            method = clazz.getDeclaredMethod(methodName,paramsTypes);
        }else {
            method = clazz.getDeclaredMethod(methodName);
        }
        return method;
    }


    private static Class<?>[] getMethodParamsType(List<Object> methodParams) {
        Class<?>[] classs = new Class<?>[methodParams.size()];
        int index = 0;
        for (Object os : methodParams)
        {
            classs[index] = os.getClass();
            index++;
        }
        return classs;
    }

    public static class TaskJob implements Job {

        private Map<Class,Object> objectMap = new ConcurrentHashMap<Class, Object>();

        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            JobDataMap dataMap = jobExecutionContext.getMergedJobDataMap();
            Class clazz = (Class) dataMap.get(CLASS_KEY);
            Object object;
            try {
                object = getObject(clazz);
                Method method = (Method) dataMap.get(METHOD_KEY);
                Parameter[] parameters = method.getParameters();
                if (parameters.length > 0) {
                    List<Object> args = (List<Object>) dataMap.get(PARAMS_KEY);
                    Object[] objects = args.toArray();
                    method.invoke(object, objects);
                }else {
                    method.invoke(object);
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }

        private Object getObject(Class clazz) throws IllegalAccessException, InstantiationException {
            Object object = objectMap.get(clazz);
            if(object == null) {
                object = clazz.newInstance();
                objectMap.put(clazz,object);
            }
            return object;
        }
    }
}

        

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值