SpringBoot2 task scheduler 定时任务调度器四种方式

使用@EnableScheduling方式

@Component
@Configurable
@EnableScheduling
public class Task1 {
    private static Log logger = LogFactory.getLog(Task1.class);
    @Scheduled(cron = "0/2 * * * * * ")
    public void execute() {
        logger.info("Task1>>" + new Date());
    }
}

xml配置方式

application启动加入读取xml文件

@SpringBootApplication
@ImportResource(value = { "classpath:applicationContext*.xml" })
public class Springboot2TaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springboot2TaskApplication.class, args);
    }
}
<context:component-scan base-package="com.chenyingjun.task.schedual"></context:component-scan>
<task:scheduler id="appScheduler" pool-size="2" /> 
<!-- 调整定时任务 -->
<task:scheduled-tasks>    
    <task:scheduled ref="task2" method="method2" cron="0/10 * * * * ?"/>
</task:scheduled-tasks>
@Service
public class Task2 {
    private static Log logger = LogFactory.getLog(Task2.class);
    public void method2() {
        logger.info("Task2----method2>>>>" + new Date());
    }
}

bean创建工厂方式

使用到的jar

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
</dependency>
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
</dependency>

新建SchedledConfiguration.java文件

@Configuration
public class SchedledConfiguration {

    /**
     * attention:
     * Details:配置定时任务
     */
    @Bean(name = "jobDetail")
    public MethodInvokingJobDetailFactoryBean detailFactoryBean(Task3 task) {// TestTask为需要执行的任务
        MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
        /*
         *  是否并发执行
         *  例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,
         *  如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
         */
        jobDetail.setConcurrent(false);

        // 设置任务的名字
        jobDetail.setName("jobDetailName");

        // 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用
        jobDetail.setGroup("jobDetailGroup");

        /*
         * 为需要执行的实体类对应的对象
         */
        jobDetail.setTargetObject(task);

        /*
         * 通过这几个配置,告诉JobDetailFactoryBean我们需要执行定时执行ScheduleTask类中的task方法
         */
        jobDetail.setTargetMethod("task");
        return jobDetail;
    }

    /**
     * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务
     */
    @Bean(name = "jobTrigger")
    public CronTriggerFactoryBean cronJobTrigger(JobDetail jobDetail) {
        CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
        tigger.setJobDetail(jobDetail);
        // 初始时的cron表达式,可以改成从数据库中获取
        tigger.setCronExpression("0/2 * * * * ?");
        // trigger的name
        tigger.setName("tiggerName");
        return tigger;

    }

    /**
     * Details:定义quartz调度工厂
     */
    @Bean(name = "scheduler")
    public SchedulerFactoryBean schedulerFactory(Trigger trigger) {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
        bean.setOverwriteExistingJobs(true);
        // 延时启动,应用启动1秒后
        bean.setStartupDelay(1);
        // 注册触发器
        bean.setTriggers(trigger);
        return bean;
    }
}

新建Task任务

@Service
public class Task3 {

    @Resource(name = "jobTrigger")
    private CronTrigger cronTrigger;

    @Resource(name = "scheduler")
    private Scheduler scheduler;

    private static Log logger = LogFactory.getLog(Task3.class);

    public void task() {
        logger.info("Task3---------" + new Date());
    }

    /**
     * 设置cron并重启定时器
     * @param cron cron值
     */
    public void setCron(String cron) {
        try {
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
            // 按新的cronExpression表达式重新构建trigger
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
            trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey())
                    .withSchedule(scheduleBuilder).build();
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(cronTrigger.getKey(), trigger);
        } catch (SchedulerException e) {
            logger.info("cron表达式错误");
        }
    }
}

其中setCron方法可以进行重新设定任务调度时间

ThreadPoolTaskScheduler Runnable方式

public class Task4 implements Runnable {

    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    private static Log logger = LogFactory.getLog(Task4.class);

    @Override
    public void run() {
        logger.info("Task4================" + new Date());
    }

    /**
     * 设置cron并启动
     * @param cronExp cron值
     */
    public void reStart(String cronExp) {
        if (null != this.threadPoolTaskScheduler) {
            ScheduledExecutorService scheduledExecutorService = this.threadPoolTaskScheduler.getScheduledExecutor();
            if (!scheduledExecutorService.isShutdown()) {
                scheduledExecutorService.shutdownNow();
            }

            this.threadPoolTaskScheduler.destroy();
        }

        if (null != cronExp && cronExp.trim().length() > 0) {
            this.threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
            this.threadPoolTaskScheduler.setThreadNamePrefix("task4");
            this.threadPoolTaskScheduler.initialize();
            this.threadPoolTaskScheduler.schedule(this, new CronTrigger(cronExp));
        }
    }
}

其中reStart可以进行任务启动和重新设置任务调度时间,调用方式如下所示

/**
     * 初始化task4
     * 这里的代码不应该写在rest层上, 应该写在service层上
     */
    @PostConstruct
    private void initTask4() {
        //初始化task4任务调度器cron,可以从数据库中查询到cron值
        setTask4Cron("0/3 * * * * ?");
    }

    /**
     * 改变task4的cron
     * @param cron cron值
     * @return 成功标志
     */
    @RequestMapping(value = { "/setTask4Cron" }, method = RequestMethod.GET)
    @ResponseBody
    public String setTask4Cron(String cron) {
        if (null == task4) {
            task4 = new Task4();
        }

        task4.reStart(cron);
        return "success";
    }

initTask4方法加了@PostConstruct'注解,可以在项目启动时自动根据cron来启动任务,setTask4Cron方法可以重新调置任务时间

四个任务的效果如下:


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容