精华内容
下载资源
问答
  • 对于quartz定时任务设置结束时间

    千次阅读 2018-09-06 15:39:42
    在使用quartz时,使用cornTrigger再设置一个结束时间 endAt(“结束的时间”),实现在任务执后自动销毁任务,在到了结束时间之后,job并不会留在内存中,job是直接被delete掉,所以不担心会有内存满的情况;...

    在使用quartz时,使用cornTrigger再设置一个结束时间 endAt(“结束的时间”),实现在任务执后自动销毁任务,在到了结束时间之后,job并不会留在内存中,job是直接被delete掉,所以不担心会有内存满的情况;

     

    代码:

    //按新的cronExpression表达式构建一个新的trigger
    trigger = TriggerBuilder.newTrigger()
            .withIdentity(triggerName, triggerGroupName)
            .withSchedule(scheduleBuilder)
            .endAt(endDate)
            .build();

    附属上查询所有job代码:

    /**
     * 查询所有的job
     */
    public static void getAllJobs(){
        try {
            Scheduler scheduler = sf.getScheduler();
            for (String groupName : scheduler.getJobGroupNames()) {
                for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
                    String jobName = jobKey.getName();
                    String jobGroup = jobKey.getGroup();
                    //get job's trigger
                    List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
                    Date nextFireTime = triggers.get(0).getNextFireTime();
                    System.out.println("[jobName] : " + jobName + " [groupName] : "
                            + jobGroup + " - " + nextFireTime);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    下面是完整的quartz工具类:

    import org.quartz.*;
    import org.quartz.impl.StdSchedulerFactory;
    import org.quartz.impl.matchers.GroupMatcher;
    import qgs.framework.core.task.JobFactory;
    import qgs.framework.util.utilty.DateUtil;
    
    import java.text.ParseException;
    import java.util.Date;
    import java.util.List;
    
    /**
     * create by XXX on 2018/09/03
     * 定时任务工具类
     */
    public class QuartzUtil {
        private static SchedulerFactory sf = new StdSchedulerFactory();
        private static JobFactory jobFactory = new JobFactory();
        private static String JOB_GROUP_NAME = "group1";
        private static String TRIGGER_GROUP_NAME = "trigger1";
    
        /**
         * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
         *
         * @param jobName  任务名
         * @param jobClass 任务类名
         * @param time     时间设置,参考quartz说明文档
         * @param data     定时任务所带参数数据
         * @param endDate  定时任务生命周期结束时间
         * @throws ParseException
         */
        public static void saveJobCron(String jobName, Class<? extends Job> jobClass, String time, JobDataMap data, Date endDate) throws Exception {
            saveJobCron(jobName, JOB_GROUP_NAME, jobName, TRIGGER_GROUP_NAME, jobClass, time, data, endDate);
        }
    
        /**
         * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
         *
         * @param jobName  任务名
         * @param jobClass 任务类名
         * @param time     时间设置,参考quartz说明文档
         * @throws ParseException
         */
        public static void saveJobCron(String jobName, Class<? extends Job> jobClass, String time) throws Exception {
            saveJobCron(jobName, JOB_GROUP_NAME, jobName, TRIGGER_GROUP_NAME, jobClass, time);
        }
    
        /** */
        /**
         * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
         *
         * @param jobName  任务名
         * @param jobClass 任务类名
         * @param time     时间间隔  每隔多少时间执行一次 单位毫秒 如 1000*60*60 = 1小时
         * @throws ParseException
         */
        public static void saveJobSimple(String jobName, Class<? extends Job> jobClass, Integer time) throws Exception {
            saveJobSimple(jobName, JOB_GROUP_NAME, jobName, TRIGGER_GROUP_NAME, jobClass, time, true);
        }
    
        public static void saveJobSimple(String jobName, Class<? extends Job> jobClass, Integer time, boolean firstRun) throws Exception {
            saveJobSimple(jobName, JOB_GROUP_NAME, jobName, TRIGGER_GROUP_NAME, jobClass, time, firstRun);
        }
    
        /** */
        /**
         * 添加一个定时任务
         *
         * @param jobName          任务名
         * @param jobGroupName     任务组名
         * @param triggerName      触发器名
         * @param triggerGroupName 触发器组名
         * @param jobClass         任务类名
         * @param time             时间间隔  每隔多少时间执行一次 单位秒 如 1000*60*60 = 1小时
         * @throws SchedulerException
         * @throws ParseException
         * @throws ParseException
         */
        public static void saveJobSimple(String jobName, String jobGroupName, String triggerName,
                                         String triggerGroupName, Class<? extends Job> jobClass, Integer time, boolean firstRun)
                throws Exception {
            Scheduler scheduler = sf.getScheduler();
            scheduler.setJobFactory(jobFactory);
    
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, triggerGroupName);
            SimpleTrigger trigger = (SimpleTrigger) scheduler.getTrigger(triggerKey);
            //不存在,创建一个
            if (null == trigger) {
                JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
                //按新的cronExpression表达式构建一个新的trigger
                TriggerBuilder s = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName);
                if (!firstRun) {
                    s.startAt(DateUtil.addSecond(new Date(), time));
                }
                trigger = (SimpleTrigger) s.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(time).repeatForever()).build();
                scheduler.scheduleJob(jobDetail, trigger);
                //启动
                if (!scheduler.isShutdown())
                    scheduler.start();
            } else {
                // Trigger已存在,那么更新相应的定时设置
                //按新的cronExpression表达式重新构建trigger
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                        .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(time).repeatForever()).build();
                //按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, trigger);
            }
        }
    
        /**
         * 添加一个定时任务
         *
         * @param jobName          任务名
         * @param jobGroupName     任务组名
         * @param triggerName      触发器名
         * @param triggerGroupName 触发器组名
         * @param jobClass         任务类名
         * @param time             时间设置,参考quartz说明文档
         * @param data             对应定时认为中所涉及的数据
         * @param endDate          定时任务周期结束时间
         * @throws SchedulerException
         * @throws ParseException
         * @throws ParseException
         */
        public static void saveJobCron(String jobName, String jobGroupName, String triggerName,
                                       String triggerGroupName, Class<? extends Job> jobClass, String time,
                                       JobDataMap data, Date endDate)
                throws Exception {
            Scheduler scheduler = sf.getScheduler();
            scheduler.setJobFactory(jobFactory);
    
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            //不存在,创建一个
            if (null == trigger) {
                JobDetail jobDetail =
                        JobBuilder.newJob(jobClass)
                                .withIdentity(jobName, jobGroupName)
                                .setJobData(data)
                                .build();
                //表达式调度构建器
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);
                //按新的cronExpression表达式构建一个新的trigger
                trigger = TriggerBuilder.newTrigger()
                        .withIdentity(triggerName, triggerGroupName)
                        .withSchedule(scheduleBuilder)
                        .endAt(endDate)
                        .build();
                scheduler.scheduleJob(jobDetail, trigger);
                //启动
                if (!scheduler.isShutdown())
                    scheduler.start();
            } else {
                // Trigger已存在,那么更新相应的定时设置
                //表达式调度构建器
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);
                //按新的cronExpression表达式重新构建trigger
                trigger = trigger.getTriggerBuilder()
                        .withIdentity(triggerKey)
                        .withSchedule(scheduleBuilder)
                        .startAt(new Date())
                        .endAt(endDate).build();
                //按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, trigger);
            }
        }
    
        /**
         * 添加一个定时任务
         *
         * @param jobName          任务名
         * @param jobGroupName     任务组名
         * @param triggerName      触发器名
         * @param triggerGroupName 触发器组名
         * @param jobClass         任务类名
         * @param time             时间设置,参考quartz说明文档
         * @throws SchedulerException
         * @throws ParseException
         * @throws ParseException
         */
        public static void saveJobCron(String jobName, String jobGroupName, String triggerName,
                                       String triggerGroupName, Class<? extends Job> jobClass, String time) throws Exception {
            Scheduler scheduler = sf.getScheduler();
            scheduler.setJobFactory(jobFactory);
    
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            //不存在,创建一个
            if (null == trigger) {
                JobDetail jobDetail =
                        JobBuilder.newJob(jobClass)
                                .withIdentity(jobName, jobGroupName)
                                .build();
                //表达式调度构建器
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);
                //按新的cronExpression表达式构建一个新的trigger
                trigger = TriggerBuilder.newTrigger()
                        .withIdentity(triggerName, triggerGroupName)
                        .withSchedule(scheduleBuilder)
                        .build();
                scheduler.scheduleJob(jobDetail, trigger);
                //启动
                if (!scheduler.isShutdown())
                    scheduler.start();
            } else {
                // Trigger已存在,那么更新相应的定时设置
                //表达式调度构建器
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);
                //按新的cronExpression表达式重新构建trigger
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                        .withSchedule(scheduleBuilder).build();
                //按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, trigger);
            }
        }
    
        /** */
        /**
         * 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
         *
         * @param jobName
         * @throws SchedulerException
         */
        public static void removeJob(String jobName) throws Exception {
            removeJob(jobName, JOB_GROUP_NAME, jobName, TRIGGER_GROUP_NAME);
        }
    
        /** */
        /**
         * 移除一个任务
         *
         * @param jobName
         * @param jobGroupName
         * @param triggerName
         * @param triggerGroupName
         * @throws SchedulerException
         */
        public static void removeJob(String jobName, String jobGroupName, String triggerName,
                                     String triggerGroupName) throws Exception {
            Scheduler scheduler = sf.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            scheduler.pauseTrigger(triggerKey);// 停止触发器
            scheduler.unscheduleJob(triggerKey);// 移除触发器
            scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务
        }
    
        public static void shutdownJobs() throws Exception {
            Scheduler scheduler = sf.getScheduler();
            try {
                if (!scheduler.isShutdown()) {
                    scheduler.shutdown();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * 查询所有的job
         */
        public static void getAllJobs(){
            try {
                Scheduler scheduler = sf.getScheduler();
                for (String groupName : scheduler.getJobGroupNames()) {
                    for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
                        String jobName = jobKey.getName();
                        String jobGroup = jobKey.getGroup();
                        //get job's trigger
                        List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
                        Date nextFireTime = triggers.get(0).getNextFireTime();
                        System.out.println("[jobName] : " + jobName + " [groupName] : "
                                + jobGroup + " - " + nextFireTime);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    展开全文
  • startAt控制开始执行时间 endAt控制结束执行时间

        startAt控制开始执行时间

        endAt控制结束执行时间

    展开全文
  • 条件触发定时任务开始和停止

    千次阅读 2019-11-08 19:47:28
    条件触发定时任务开始和停止 业务需求:答题游戏开始后,每5s统计一次结果。答题答完10次后,停止定时任务。 第一步:springBoot启动类的设置 @SpringBootApplication @EnableScheduling public class App { // ...

    条件触发定时任务的开始和停止

    业务需求:答题游戏开始后,每m秒统计一次结果。答题答完n次后,停止定时任务。
    

    第一步:springBoot启动类的设置

    @SpringBootApplication
    @EnableScheduling
    public class App {
        // 线程存储器
        public static ConcurrentHashMap<String, ScheduledFuture> map = new ConcurrentHashMap<String, ScheduledFuture>();
    
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    
        // 创建线程
        @Bean
        public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
            ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
            executor.setPoolSize(20);
            executor.setThreadNamePrefix("threadPoolTaskSchedulerExecutor-");
            executor.setWaitForTasksToCompleteOnShutdown(true);
            //等待线程结束时间60s
            executor.setAwaitTerminationSeconds(60);
            return executor;
        }
    }
    

    第二步:主体代码

    @Controller
    @RequestMapping("/api")
    public class A {
        private static Logger logger = LoggerFactory.getLogger(A.class);
        @Autowired
        private ThreadPoolTaskScheduler threadPoolTaskScheduler;
    
        private ScheduledFuture<?> future;
    
        @RequestMapping("/startTask")
        public void method(String teamId) {
            Date date = new Date();
            logger.info("开始进入的时间为 [{}]", date.toLocaleString());
            Calendar instance = Calendar.getInstance();
            instance.setTime(date);
            instance.add(Calendar.SECOND, 2);
            Date time = instance.getTime();
            logger.info("定时任务开始时间为 [{}]", time.toLocaleString());
            //设置定时任务的trigger
            //ScheduledFuture<?> schedule1 = threadPoolTaskScheduler.schedule(new DemoTask(teamId), new CronTrigger("*/5 * * * * *"));
            //设置任务的开始时间和开始之后的执行频率(5s执行一次)
            ScheduledFuture<?> schedule1 = threadPoolTaskScheduler.scheduleWithFixedDelay(new DemoTask(teamId), time, 5000);
            App.map.put(teamId, schedule1);
        }
    
        public void stopTask(String teamId) {
            logger.info("真的调用了停止定时任务的方法!");
            ScheduledFuture future = App.map.get(teamId);
            if (future != null) {
                future.cancel(true);
            }
            logger.info("end!");
        }
    
        class DemoTask implements Runnable {
            private String teamId;
    
            private int count = 1;
    
            public int getCount() {
                return count;
            }
    
            public void setCount(int count) {
                this.count = count;
            }
    
            public DemoTask(String teamId) {
                this.teamId = teamId;
            }
    
            public String getTeamId() {
                return teamId;
            }
    
            public void setTeamId(String teamId) {
                this.teamId = teamId;
            }
    
            @Override
            public void run() {
                logger.info("进入定时任务的主体!");
                int count1 = this.getCount();
                count1 = count1 + 1;
                logger.info("增加后的次数为:" + count1);
                this.setCount(count1);
                if (count1 > 5) {
                    logger.info("开始调用暂停定时任务的方法!" + teamId);
                    stopTask(teamId);
                }
            }
        }
    }
    
    展开全文
  • spring定时任务时间格式cronExpression设置

    org.springframework.scheduling.quartz.CronTriggerBean允许你更精确地控制任务的运行时间,只需要设置其cronExpression属性。
    一个cronExpression表达式有至少6个(也可能是7个)由空格分隔的时间元素。从左至右,这些元素的定义如下:
    1.秒(0–59)
    2.分钟(0–59)
    3.小时(0–23)
    4.月份中的日期(1–31)
    5.月份(1–12或JAN–DEC)
    6.星期中的日期(1–7或SUN–SAT)
    7.年份(1970–2099)
    0 0 10,14,16 * * ? 每天上午10点,下午2点和下午4点
    0 0,15,30,45 * 1-10 * ? 每月前10天每隔15分钟
    30 0 0 1 1 ? 2012 在2012年1月1日午夜过30秒时
    0 0 8-5 ? * MON-FRI 每个工作日的工作时间 

    各个时间可用值如下:
    秒 0-59 , – * /
    分 0-59 , – * /
    小时 0-23 , – * /
    日 1-31 , – * ? / L W C
    月 1-12 or JAN-DEC , – * /
    周几 1-7 or SUN-SAT , – * ? / L C #
    年 (可选字段) empty, 1970-2099 , – * /

    可用值详细分析如下:

    “*”——字符可以用于所有字段,在“分”字段中设为”*”表示”每一分钟”的含义。

    “?”——字符可以用在“日”和“周几”字段. 它用来指定 ‘不明确的值’. 这在你需要指定这两个字段中的某一个值而不是另外一个的时候会被用到。在后面的例子中可以看到其含义。

    “-”——字符被用来指定一个值的范围,比如在“小时”字段中设为”10-12″表示”10点到12点”。

    “,”——字符指定数个值。比如在“周几”字段中设为”MON,WED,FRI”表示”the days Monday, Wednesday, and Friday”。

    “/”——字符用来指定一个值的的增加幅度. 比如在“秒”字段中设置为”0/15″表示”第0, 15, 30, 和 45秒”。而 “5/15″则表示”第5, 20, 35, 和 50″. 在’/'前加”*”字符相当于指定从0秒开始. 每个字段都有一系列可以开始或结束的数值。对于“秒”和“分”字段来说,其数值范围为0到59,对于“小时”字段来说其为0到23, 对于“日”字段来说为0到31, 而对于“月”字段来说为1到12。”/”字段仅仅只是帮助你在允许的数值范围内从开始”第n”的值。

    “L”——字符可用在“日”和“周几”这两个字段。它是”last”的缩写, 但是在这两个字段中有不同的含义。例如,“日”字段中的”L”表示”一个月中的最后一天” —— 对于一月就是31号对于二月来说就是28号(非闰年)。而在“周几”字段中, 它简单的表示”7″ or “SAT”,但是如果在“周几”字段中使用时跟在某个数字之后, 它表示”该月最后一个星期×” —— 比如”6L”表示”该月最后一个周五”。当使用’L'选项时,指定确定的列表或者范围非常重要,否则你会被结果搞糊涂的。

    “W”——可用于“日”字段。用来指定历给定日期最近的工作日(周一到周五) 。比如你将“日”字段设为”15W”,意为: “离该月15号最近的工作日”。因此如果15号为周六,触发器会在14号即周五调用。如果15号为周日, 触发器会在16号也就是周一触发。如果15号为周二,那么当天就会触发。然而如果你将“日”字段设为”1W”, 而一号又是周六, 触发器会于下周一也就是当月的3号触发,因为它不会越过当月的值的范围边界。’W'字符只能用于“日”字段的值为单独的一天而不是一系列值的时候。

    “L”和“W”可以组合用于“日”字段表示为’LW’,意为”该月最后一个工作日”。

    “#”—— 字符可用于“周几”字段。该字符表示“该月第几个周×”,比如”6#3″表示该月第三个周五( 6表示周五而”#3″该月第三个)。再比如: “2#1″ = 表示该月第一个周一而 “4#5″ = 该月第五个周三。注意如果你指定”#5″该月没有第五个“周×”,该月是不会触发的。

    “C”—— 字符可用于“日”和“周几”字段,它是”calendar”的缩写。 它表示为基于相关的日历所计算出的值(如果有的话)。如果没有关联的日历, 那它等同于包含全部日历。“日”字段值为”5C”表示”日历中的第一天或者5号以后”,“周几”字段值为”1C”则表示”日历中的第一天或者周日以后”。

    对于“月份”字段和“周几”字段来说合法的字符都不是大小写敏感的。


    一些例子:

    [javascript]  view plain  copy
    1. <span style="font-size:18px;">关于cronExpression表达式:   
    2. 字段 允许值 允许的特殊字符   
    3. 秒 0-59 , - * /   
    4. 分 0-59 , - * /   
    5. 小时 0-23 , - * /   
    6. 日期 1-31 , - * ? / L W C   
    7. 月份 1-12 或者 JAN-DEC , - * /   
    8. 星期 1-7 或者 SUN-SAT , - * ? / L C #   
    9. 年(可选) 留空, 1970-2099 , - * /   
    10. 表达式意义   
    11. "0 0 12 * * ?" 每天中午12点触发   
    12. "0 15 10 ? * *" 每天上午10:15触发   
    13. "0 15 10 * * ?" 每天上午10:15触发   
    14. "0 15 10 * * ? *" 每天上午10:15触发   
    15. "0 15 10 * * ? 2005" 2005年的每天上午10:15触发   
    16. "0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发   
    17. "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发   
    18. "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发   
    19. "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发   
    20. "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发   
    21. "0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发   
    22. "0 15 10 15 * ?" 每月15日上午10:15触发   
    23. "0 15 10 L * ?" 每月最后一日的上午10:15触发   
    24. "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发   
    25. "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发   
    26. "0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发   
    27. 每天早上6点   
    28. 0 6 * * *   
    29. 每两个小时   
    30. 0 */2 * * *   
    31. 晚上11点到早上8点之间每两个小时,早上八点   
    32. 0 23-7/2,8 * * *   
    33. 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点   
    34. 0 11 4 * 1-3   
    35. 1月1日早上4点   
    36. 0 4 1 1 *</span>  


    Quartz spring中动态设置cronExpression


    什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。

    这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文件,但总需要重新启动web服务啊,研究了下Quartz在Spring中的动态定时,发现<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >

             <property name="jobDetail" ref="schedulerJobDetail"/>

             <property name="cronExpression">

                 <value>0/10 * * * * ?</value>

             </property>

          中cronExpression是关键,如果可以动态设置cronExpression的值,也就说如果我们可以直接调用CronTriggerBean中设置cronExpression的方法,就可以顺利解决问题了。

    熟悉1的朋友可以跳过不看,下面2、3是动态定时任务的具体实现。

     

    1.  Quartz 在Spring中的简单配置

    Spring 配置文件:

        <bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

            <property name="targetObject" ref="scheduleInfoAction"/>

            <property name="targetMethod" value="simpleJobTest"/>

            <property name="concurrent" value="false"/>

        </bean>

        <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >

             <property name="jobDetail" ref="schedulerJobDetail"/>

             <property name="cronExpression">

                 <value>0/10 * * * * ?</value>

             </property>

         </bean>

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

            <property name="triggers">

                <list>

                    <ref local="cronTrigger"/>

                </list>

            </property>

    </bean>

     

    在上面的配置中设定了

    ① targetMethod: 指定需要定时执行scheduleInfoAction中的simpleJobTest()方法

    ② concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,第二个job就开始了。指定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始。

    ③ cronExpression:0/10 * * * * ?表示每10秒执行一次,具体可参考附表

    ④ triggers:通过再添加其他的ref元素可在list中放置多个触发器。

     

    scheduleInfoAction 中的simpleJobTest()方法

    注意:此方法没有参数,如果scheduleInfoAction有两个方法simpleJobTest()和simpleJobTest(String argument),则spring只会去执行无参的simpleJobTest().

    public void simpleJobTest() { 

            log.warn("uh oh, Job is scheduled !'" + "' Success...");

        }

     

    2 .Quartz在Spring中动态设置cronTrigger方法一

    Spring 配置文件:

    <bean id="scheduleInfoAction" class="com.lively.happyoa.jobs.webapp.action.ScheduleInfoAction">

            <property name="scheduler" ref="schedulerFactory"/>

            <property name="scheduleInfoManager" ref="scheduleInfoManager"/>

        </bean>

        <bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

            <property name="targetObject" ref="scheduleInfoAction"/>

            <property name="targetMethod" value="reScheduleJob"/>

            <property name="concurrent" value="false"/>

        </bean>

        <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >

             <property name="jobDetail" ref="schedulerJobDetail"/>

             <property name="cronExpression">

                 <value>0/10 * * * * ?</value>

             </property>

         </bean>

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

            <property name="triggers">

                <list>

                    <ref local="cronTrigger"/>

                </list>

            </property>

    </bean>

     

    scheduleInfoAction 中的reScheduleJob ()方法及相关方法

    ① reScheduleJob():读取数据库,获得自定义定时器调度时间

        private void reScheduleJob() throws SchedulerException, ParseException {

            // 运行时可通过动态注入的scheduler得到trigger

            CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(

                     "cronTrigger", Scheduler.DEFAULT_GROUP);

            String dbCronExpression = getCronExpressionFromDB();

            String originConExpression = trigger.getCronExpression();

        // 判断从DB中取得的任务时间(dbCronExpression)和现在的quartz线程中的任务时间(originConExpression)是否相等

        // 如果相等,则表示用户并没有重新设定数据库中的任务时间,这种情况不需要重新rescheduleJob

            if(!originConExpression.equalsIgnoreCase(dbCronExpression)){

                trigger.setCronExpression(dbCronExpression);

                scheduler.rescheduleJob("cronTrigger", Scheduler.DEFAULT_GROUP, trigger);

            }

        // 下面是具体的job内容,可自行设置

        // executeJobDetail();

    }

     

    ② getCronExpressionFromDB():从数据库中获得dbCronExpression的具体代码,由于使用了scheduleInfoManager,所以要在定义相应的setter方法

        private String getCronExpressionFromDB(){

            String sql="from ScheduleInfo scheduleInfo where 1=1 ";

            sql=sql+" and scheduleInfo.infoId = '"+"1" + "'";

            List scheduleList = scheduleInfoManager.queryScheduleInListBySql(sql);

            ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleList.get(0);

            String dbCronExpression = scheduleInfo.getCronExpression();

            return dbCronExpression;

    }

     

    ③ 在spring配置文件的scheduleInfoAction配置了相应的property(scheduler/scheduleInfoManager),要为其设置setter方法

        private Scheduler scheduler;

        // 设值注入,通过setter方法传入被调用者的实例scheduler

        public void setScheduler(Scheduler scheduler) {

            this.scheduler = scheduler;

         }

        private ScheduleInfoManager scheduleInfoManager;

        // 设值注入,通过setter方法传入被调用者的实例scheduleInfoManager

        public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){

            this.scheduleInfoManager = scheduleInfoManager;

        }

     

    3.  Quartz 在Spring中动态设置cronTrigger方法二

    在上面的2中我们可以看到,尽管 已经可以动态进行 rescheduleJob 了,不过依然需要我们设置一个 cronExpression ,如果尝试一下拿掉spring配置中的

            <property name="cronExpression">

                 <value>0/10 * * * * ?</value>

             </property>

    则容器(如tomcat)启动时会报错。

    实际中我们希望tomcat启动时就可以直接去读数据库,拿到相应的 dbCronExpression ,然后定时执行一个job,而不希望配置初始的 cronExpression ,观察下面的 CronTriggerBean ,考虑到cronExpression需要初始化,如果设定一个类InitializingCronTrigger继承CronTriggerBean,然后在这个类中做一些读取DB的初始化工作(设置cronExpression),问题就可以解决了。

     

    Spring 配置文件:

    <bean id="scheduleInfoAction" class="com.lively.happyoa.jobs.webapp.action.ScheduleInfoAction">

            <property name="scheduler" ref="schedulerFactory"/>

            <property name="scheduleInfoManager" ref="scheduleInfoManager"/>

        </bean>

        <bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

            <property name="targetObject" ref="scheduleInfoAction"/>

            <property name="targetMethod" value="reScheduleJob"/>

            <property name="concurrent" value="false"/>

        </bean>

         <bean id="cronTrigger" class="com.lively.happyoa.jobs.webapp.action.ScheduleInfoAction.InitializingCronTrigger">

             <property name="jobDetail" ref="schedulerJobDetail"/>

             <!--<property name="cronExpression">

                 <value>0/10 * * * * ?</value>

             </property>-->

             <property name="scheduleInfoManager" ref="scheduleInfoManager"/>

         </bean>

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

            <property name="triggers">

                <list>

                    <ref local="cronTrigger"/>

                </list>

            </property>

    </bean>

     

    InitializingCronTrigger 中的相关方法

    注意:在注入scheduleInfoManager属性的时候,我们可以去读取DB任务时间(之所以放在setter方法中,是因为需要在设置scheduleInfoManager后进行getCronExpressionFromDB(),否则,也可以①②逻辑把放在类的构造函数中).

    注意InitializingCronTrigger必须extendsCronTriggerBean.

     

    public class InitializingCronTrigger extendsCronTriggerBean implements Serializable {

        private ScheduleInfoManager scheduleInfoManager;

        // 设值注入,通过setter方法传入被调用者的实例scheduleInfoManager

        public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){

            this.scheduleInfoManager = scheduleInfoManager;

            // 因为在getCronExpressionFromDB使用到了scheduleInfoManager,所以

            // 必须上一行代码设置scheduleInfoManager后进行getCronExpressionFromDB

            String cronExpression = getCronExpressionFromDB ();   // 

            // 因为extendsCronTriggerBean ,此处调用父类方法初始化cronExpression

            setCronExpression (cronExpression);                    // 

    }

        private String getCronExpressionFromDB(){

            String sql="from ScheduleInfo scheduleInfo where 1=1 ";

            sql=sql+" and scheduleInfo.infoId = '"+"1" + "'";

            List scheduleList = scheduleInfoManager.queryScheduleInListBySql(sql);

            ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleList.get(0);

            String dbCronExpression = scheduleInfo.getCronExpression();

            return dbCronExpression;

     }

    ……

    }


    展开全文
  • Spring设置定时任务时,关于执行时间的规则设置2016年10月13日 23:24:16阅读数:24529Spring设置一个定时任务,可能有如下配置:[html] view plain copy&lt;?xml version="1.0" encoding="...
  • quartz定时任务时间设置

    千次阅读 2014-12-11 14:52:00
    3 WED 3月分每周三下午的 2点10分2点44分触发 (特殊情况,在一个时间设置里,执行两次或 两次以上的情况)  0 59 2 ? * FRI 每周5凌晨2点59分触发;  0 15 10 ? * MON-FRI 从周一到周五每天上午的10...
  • oracle定时任务中的时间设置

    千次阅读 2017-04-18 14:38:08
    1、简单的定时任务时间设置。 描述  参数值 每天运行一次 'SYSDATE + 1' 每小时运行一次 ‘SYSDATE+1/24’ 每10分钟运行一次 'SYSDATE + 10/(60*24)' 每30秒运行一次 'SYSDATE + 30/(60*24*60)'...
  • Cron 定时任务 时间设置

    千次阅读 2017-05-08 11:27:37
    CronTrigger CronTriggers往往比...CronTrigger,你可以指定触发的时间表如“每星期五中午”,或“每个工作日9:30时”,甚至“每5分钟一班9:0010:00逢星期一上午,星期三星期五“。 即便如此,SimpleTrigger
  • spring 定时任务的 执行时间设置规则

    万次阅读 多人点赞 2012-12-13 23:33:23
    org.springframework.scheduling.quartz.CronTriggerBean允许你更精确地控制任务的运行时间,只需要设置其cronExpression属性。 一个cronExpression表达式有至少6个(也可能是7个)由空格分隔的时间元素。从左至右...
  • 定时任务的 执行时间设置规则

    千次阅读 2019-05-15 11:20:31
    spring 定时任务的 执行时间设置规则 单纯针对时间设置规则 org.springframework.scheduling.quartz.CronTriggerBean允许你更精确地控制任务的运行时间,只需要设置其cronExpression属性。 一个cronExpression...
  • mysql设置定时任务

    千次阅读 2019-06-27 10:43:35
    mysql设置定时任务 一、 首先我们要开启 mysql的定时策略 执行 show variables like '%event_sche%'; 如果数据为 off表示没开启 开启 set global event_scheduler=1; 二、 创建procedure(存储过程) ...
  • ThinkPHP5.1定时任务设置及传参

    千次阅读 2020-05-25 14:14:30
    ThinkPHP5.1定时任务设置及传参 1.在相关模块中创建command文件夹,与controller/model/view目录同级 2.在command中创建任务文件 <?php namespace app\index\command; use think\console\Command; use ...
  • windows下定时任务设置 脚本

    千次阅读 2019-08-12 16:05:41
    为了批量添加定时任务计划,方便操作研究了一下 schtasks 命令 命令说明 schtasks schtasks create 创建新的计划任务。 语法 schtasks /create /tn TaskName /tr TaskRun /sc schedule [/mo modifier] [/d day] [/...
  • Java 5 推出了基于线程池设计的 ScheduledExecutor。其设计思想是,每一个被调度的任务都会由线程池中一个线程去...定时任务即在指定的时间间隔重复执行任务 //定时任务 ScheduledExecutorService service = Execu
  • // 设置任务内容 JobDataMap jobDataMap = new JobDataMap(); // 需要保存spring的bean类 才能反射出 调用方法 jobDataMap.put("targetObject", springContext.getBean("...
  • Quartz使用类似于Linux下的Cron表达式定义时间规则,Cron表达式由6或7个由空格分隔的时间字段组成。 Cron表达式时间字段(从左到右依次为): 位置 时间域名 允许值 允许的特殊字符 1 秒 0-59 ...
  • JAVA定时任务-动态修改定时任务时间

    千次阅读 2020-05-23 18:40:02
    最近有个需求是这样的: 实现一个HDFS的Bucket.在总大小超过128M或10分钟内没有新文件时,进行上传操作. 所以需要实现一个可以修改定时时间定时任务. 代码如下
  • Springboot整合异步任务和定时任务

    万次阅读 2020-02-28 00:19:31
    使用Springboot整合的定时任务和异步任务处理
  • 该方式采用轮询方式,开启定时任务,扫描是否需要提交的试卷,也想采用每一张试卷开始考试创建一个定时任务,但是我测试时候发现,定时任务执行的时间不准确,一般快于正常的倒计时时间,所有采用轮询, 提交时候...
  • windows下的定时任务设置详解

    万次阅读 2017-01-09 15:11:25
    windows批处理文件PHP运行模式phpexePHP执行代码创建任务计划 ...因为在项目中有个需求是大批量的数据自动计算后插入更新到数据库中,为避免占用正常资源,需要在固定时间段进行自动计算,因为项目服务器是windows s
  • spring定时任务设置有两种方式,注解xml配置。推荐使用注解,在本文章也主要介绍注解方式配置 一:注解方式配置定时任务: 下面的步骤默认spring的其他配置项都已经配置好(比如启动注解配置,包路径扫描等) 1:...
  • spring boot设置定时任务

    万次阅读 2018-09-11 10:59:28
    使用定时任务完成一些业务逻辑,比如天气接口的数据获取,定时发送短信,邮件。以及商城中每天用户的限额,定时自动收货等等。定时器在项目中是常常会使用到的一个手段。 定时任务在Spring Boot中的集成 在启动...
  • @EnableScheduling @Scheduled有三种配置方式 cron fixedRate fixedDelay cron是固定时间进行处理 ...fixedDelay任务执行间隔是前次任务结束和下次任务开始点 这篇文章主要探讨的是如果任务执行时间超过了定...
  • 这里写目录标题定时任务的实现方式Spring Task的使用总结 定时任务的实现方式 1、Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 80,208
精华内容 32,083
关键字:

定时任务设置开始和结束时间