为了账号安全,请及时绑定邮箱和手机立即绑定

SpringBoot整合实现定时任务

https://img1.sycdn.imooc.com//5e15f10500016ecb14401080.jpg

一、定时任务实现的几种方式

1. Timer:线程调度任务以供将来在后台线程中执行的功能。 任务可以安排一次执行,或定期重复执行。Timer是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。

API文档:http://www.matools.com/file/manual/jdk_api_1.8_google/index.html?overview-summary.html


2. ScheduledExecutorService:也jdk自带的一个类,位于java.util.concurrent包下;它是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。

API文档:http://www.matools.com/file/manual/jdk_api_1.8_google/index.html?overview-summary.html


3. Spring Task:Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。

官方文档:https://spring.io/guides/gs/scheduling-tasks/


4. Quartz:是一个由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。这是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂。它允许程序开发人员根据时间的间隔来调度作业,并且实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。官网:http://www.quartz-scheduler.org/


5. 第三方定时任务调度工具,比如:xxl-job(https://gitee.com/xuxueli0323/xxl-job)

二、SpringBoot整合实现几种定时任务

1. 创建SpringBoot项目,引入相关的jar包到pom.xml文件

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>

其他jar包都是自带的,不用导入了

2. 创建的项目结构如下:

https://img1.sycdn.imooc.com//5e15e9d70001bab204410868.jpg

3. 代码实现

(1)配置类:

AsyncConfig.java ——异步任务配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

/**
 * @ClassName: AsyncConfig
 * @Author: liuhefei
 * @Description: 定义一个支持异步任务的配置类
 * @Date: 2019/10/31 18:53
 */
@Configuration   //表明该类是一个配置类
@EnableAsync //开启异步事件的支持
public class AsyncConfig {

    /*
     *此处成员变量应该使用@Value从配置中读取
     */
    private int corePoolSize = 10;
    private int maxPoolSize = 200;
    private int queueCapacity = 10;

    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.initialize();
        return executor;
    }
}

QuartzConfig.java——Quartz调度任务配置类

import com.lhf.springboot.quartz.QuartzTest;
import com.lhf.springboot.quartz.QuartzTest1;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ClassName: QuartzConfig
 * @Author: liuhefei
 * @Description: Quartz定时任务配置类
 * @Date: 2019/10/31 19:06
 */
@Configuration
public class QuartzConfig {

    @Bean
    public JobDetail quartzDetail(){
        return JobBuilder.newJob(QuartzTest.class).withIdentity("quartzTest").storeDurably().build();

    }

    @Bean
    public Trigger quartzTrigger(){
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(15)  //设置时间周期单位秒
                .repeatForever();
        return TriggerBuilder.newTrigger().forJob(quartzDetail())
                .withIdentity("quartzTestJob")
                .withSchedule(scheduleBuilder)
                .build();
    }

    /*****************************************************************************************************************/

    @Bean
    public JobDetail interviewPlansJobDetail(){
        return JobBuilder.newJob(QuartzTest1.class)//PrintTimeJob我们的业务类
                .withIdentity("quartzTest1")//可以给该JobDetail起一个id
                //每个JobDetail内都有一个Map,包含了关联到这个Job的数据,在Job类中可以通过context获取
                .usingJobData("msg1", "quartzTest1")//关联键值对
                .storeDurably()//即使没有Trigger关联时,也不需要删除该JobDetail
                .build();
    }
    @Bean
    public Trigger interviewPlansJobTrigger() {
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/3 * * * ? ");   // 0 0 0/1 * * ?
        return TriggerBuilder.newTrigger()
                .forJob(interviewPlansJobDetail())//关联上述的JobDetail
                .withIdentity("quartzTestJob1")//给Trigger起个名字
                .withSchedule(cronScheduleBuilder)
                .build();
    }
}

(2)quartz实现定时任务

QuartzTest.java——quartz定时任务1

import com.lhf.springboot.util.RandomUtils;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * @ClassName: QuartzTest
 * @Author: liuhefei
 * @Description: Quartz定时任务
 * @Date: 2019/10/31 19:08
 */
public class QuartzTest extends QuartzJobBean {
    //执行定时任务
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("quartz定时任务1: " + RandomUtils.getRandomString());
    }
}

QuartzTest1.java——quartz定时任务2

import com.lhf.springboot.util.RandomUtils;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * @ClassName: QuartzTest1
 * @Author: liuhefei
 * @Description: Quartz定时任务
 * @Date: 2019/10/31 19:17
 */
public class QuartzTest1 extends QuartzJobBean {

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("quartz定时任务2: " + RandomUtils.getRandomNum(4) + "-->" + RandomUtils.getRandomString());
    }
}

(3)ScheduledExecutorService实现定时任务

ScheduledExecutorServiceDemo.java

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.Date;

/**
 * @ClassName: ScheduledExecutorServiceDemo
 * @Author: liuhefei
 * @Description: ScheduledExecutorService实现定时任务
 * @Date: 2019/10/31 18:22
 */
public class ScheduledExecutorServiceDemo {

    public void scheduledJob(){

        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

        //参数:1.任务名称 2. 首次执行的延时时间 3. 任务执行间隔 4. 间隔时间单位
        service.scheduleAtFixedRate(()->System.out.println("ScheduledExecutorService Job : " + new Date()), 0, 4, TimeUnit.SECONDS);

    }
}

(4)Spring Task实现定时任务

AsyncTask.java——开启异步任务

import com.lhf.springboot.util.RandomUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * @ClassName: AsyncTask
 * @Author: liuhefei
 * @Description: TODD
 * @Date: 2019/10/31 18:57
 */
@Async  //开启异步任务类,类中的每个方法都是定时任务,该注解可以加到类和方法上
@Component
public class AsyncTask {

    //@Async
    @Scheduled(cron = "0/7 * * * * * ")
    public void task1(){
        System.out.println("异步任务1: " + System.currentTimeMillis());
    }

    //@Async
    @Scheduled(cron = "0/9 * * * * * ")
    public void task2(){
        System.out.println("异步任务2:" + RandomUtils.getRandomString());
    }
}

SpringTaskDemo.java

import com.lhf.springboot.util.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Date;

/**
 * @ClassName: SpringTaskDemo
 * @Author: liuhefei
 * @Description: Spring Task实现定时任务
 * @Date: 2019/10/31 18:31
 */
@Component
public class SpringTaskDemo {

    private final Logger logger = LoggerFactory.getLogger(SpringTaskDemo.class);

    @Scheduled(cron = "0/5 * * * * * ")
    public void scheduledCron(){
        logger.info("===>>使用cron表达式实现定时任务:" + System.currentTimeMillis());
    }

    @Scheduled(fixedRate = 6000)
    public void scheduledFixedRate(){
        logger.info("===>>使用fixedRate实现定时任务: " + RandomUtils.getRandomString(8));
    }

    @Scheduled(fixedDelay = 7000)
    public void scheduledFixedDelay(){
        logger.info("===>>使用fixedDelay实现定时任务: " + new Date() + " -- " +  RandomUtils.getRandomString(4));
    }
}

(5)Timer实现定时任务

TimerDemo.java

import com.lhf.springboot.util.RandomUtils;

import java.util.Timer;
import java.util.TimerTask;

/**
 * @ClassName: TimerDemo
 * @Author: liuhefei
 * @Description: Timer定时任务
 * @Date: 2019/10/31 17:58
 */
public class TimerDemo {

   public void timerJob(){
       TimerTask timerTask = new TimerTask() {
           @Override
           public void run() {
               System.out.println("Timer Job: " + RandomUtils.getRandomString());
           }
       };
       Timer timer = new Timer();
       //每3秒执行一次
       timer.schedule(timerTask, 10, 3000);
   }
}

(6)工具类

RandomUtils.java——随机生成字符串工具类

import java.util.Random;

/**
 * @ClassName: RandomUtils
 * @Desc: 生成随机字符串
 * @Author: liuhefei
 * @Date: 2019/2/28 14:16
 */
public class RandomUtils {
    public static String getRandomString(int length){
        //1.  定义一个字符串(A-Z,a-z,0-9)即62个数字字母;
        //String str="zxcvbnmlkjhgfdsaqwertyuiopQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
        String str="用我三生烟火,换你一世迷离。长街长,烟花繁,你挑灯回看,短亭短,红尘辗,我把萧再叹。终是谁使弦断,花落肩头,恍惚迷离多少红颜悴,多少相思碎,唯留血染墨香哭乱冢。苍茫大地一剑尽挽破,何处繁华笙歌落。斜倚云端千壶掩寂寞,纵使他人空笑我。任他凡事清浊,为你一笑间轮回甘堕。寄君一曲,不问曲终人聚散。谁将烟焚散,散了纵横的牵绊。听弦断,断那三千痴缠。坠花湮,湮没一朝风涟。花若怜,落在谁的指尖。灯火星星,人声杳杳,歌不尽乱世烽火。如花美眷,似水流年,回得了过去,回不了当初。似此星辰非昨夜,为谁风露立中宵。蝴蝶很美,终究蝴蝶飞不过沧海。山河拱手,为君一笑 。待浮花浪蕊俱尽,伴君幽独。";

        //2.  由Random生成随机数
        Random random=new Random();
        StringBuffer sb=new StringBuffer();
        //3.  长度为几就循环几次
        for(int i=0; i<length; ++i){
            //从62个的数字或字母中选择
            int number=random.nextInt(62);
            //将产生的数字通过length次承载到sb中
            sb.append(str.charAt(number));
        }
        //将承载的字符转换成字符串
        return sb.toString();
    }

    public static String getRandomString(){
        String[] strArr= {"乾坤有序,宇宙无疆,星辰密布,斗柄指航。",
                "昼白夜黑,日明月亮,风驰雪舞,电闪雷响。",
                "云腾致雨,露结晨霜,虹霓霞辉,雾沉雹降。",
                "春生夏长,秋收冬藏,时令应候,寒来暑往。",
                "远古洪荒,海田沧桑,陆地漂移,板块碰撞。",
                "山岳巍峨,湖泊荡漾,植被旷野,岛撒汪洋。",
                "冰川冻土,沙漠沃壤,木丰树森,岩多滩广。",
                "鸟飞兽走,鳞潜羽翔,境态和谐,物种安详。",
                "形分上下,道合阴阳,幽冥杳渺,天体著彰。",
                "凝气为精,聚能以场,缩浓而质,积微显量。",
                "化巨幻虚,恍惚成象,强固凌弱,柔亦制刚。",
                "终极必反,存兴趋亡,色空轮回,动静恒常。",
                "唯实众名,一理万方,父母爹娘,没齿难忘。",
                "兄弟姐妹,危困助帮,姑姨叔舅,亲戚互访。",
                "侄男闺少,哺育茁壮,夫妻相敬,梦忆糟糠。",
                "隔屋邻舍,遇事谦谅,伯公妪婆,慈孝赡养。",
                "尊朋礼友,仁义君郎,炎黄二帝,尧舜禅让。",
                "禹启世袭,灭桀商汤,周武伐纣,侯列各邦。",
                "秦皇集权,汉刘楚项,鼎立割据,乱晋八王。",
                "南北对峙,腐朽隋炀,贞观政要,五代续唐。",
                "陈桥兵变,耻辱靖康,耶律完颜,元建宋僵。",
                "钟离太祖,崇祯吊丧,清军入关,大臣驻藏。",
                "粉碎叛卓,犁域设将,台湾复归,守卫边防。",
                "鸦片战争,英占香港,戊戌维新,社会改良。",
                "辛亥革命,孙文思想,联盟抗倭,国共两党。",
                "定都京师,人民解放,诸子百家,孔孟老庄。",
                "扁鹊灵医,鲁班巧匠,罗盘硝药,针灸疗伤。",
                "蔡伦毕升,鉴真玄奘,易经论语,史记达畅。",
                "河图洛书,算术九章,西三红水,聊儒瓶厢。",
                "诗词曲赋,戏剧说唱,琵琶琴瑟,锣镲铿锵。",
                "笙箫呜咽,卧笛悠扬,筝音奔奋,唢呐高亢。",
                "荆浩匡庐,董源潇湘,米芾写意,悲鸿骏昂。",
                "笔墨纸砚,匾楣楹榜,楷隶篆刻,碑帖草狂。",
                "敦煌石窟,长城伟墙,青铜甲骨,缕衣纱裳。",
                "虎符越剑,陶马俑葬,彩瓷宝瓮,丝绸他乡。",
                "凡尔赛宫,金字塔状,泰姬陵墓,彼得教堂。",
                "自由女神,希腊塑像,最后晚餐,创造亚当。",
                "亭榭楼阁,寺庙殿廊,蓬门荜户,丈室绿窗。",
                "府弟别墅,画栋雕梁,庭院踏步,影屏幕障。",
                "承尘藻井,篱笆柱桩,舷舵扶靠,凭栏眺望。",
                "悬崖峭壁,峰峦叠嶂,泉喷岚罩,湍急瀑宕。",
                "峡沟潭渊,溪涧流淌,池渠堰坝,沼泽泥塘。",
                "漩涡带波,礁屿连江,汹涌澎湃,惊涛骇浪。",
                "灾涝溢泻,汛潮浮涨,苍松寿柏,垂柳毛杨。",
                "芭蕉蒲扇,斑竹篾筐,槐椿榆桦,杉桂榕樟。",
                "斋扉紧闭,栅苑濒旁,坪埔莱茵,菲窥坞坊。",
                "蔷薇翩跹,莆菏蔚茫,蕴蒂荚芯,蓓蕾琳琅。",
                "奇花异卉,艳丽荣秧,兰荷菊梅,四季芬芳。",
                "杜鹃泣血,芙蓉吉祥,茉莉馥郁,玫瑰刺芒。",
                "瓜果蔬菜,葱蒜韭姜,茴椒芹葵,皮芥辣酱。",
                "芸苔芋笋,葫芦瓢瓤,番茄蘑菇,乳蛋醇酿。",
                "碘盐食醋,脆卜甜糖,珍馐旨甘,肴馔膏粱。",
                "葡萄美酒,玉液琼浆,咖啡益智,茗茶顺肠。",
                "桃李杏柿,汁鲜味爽,椰柚橙桔,渴饮品尝。",
                "菠萝柑橘,橄榄槟榔,梨枣苹楂,荔栗榴棠。",
                "蝌蚪摆尾,蛤蟆鼓囊,钓饵蚯蚓,蠕虫蚂蟥。",
                "鹦鹉学舌,蜜蜂穿忙,蝙蝠栖洞,梧桐引凰。",
                "蜘蛛牵补,螟蛉蛀粮,蜻蜓振翅,鸠鹏张膀。",
                "鸥莺燕雀,蝴蝶鸳鸯,鲤鲫鲇鲸,蛙蚌螺螃。",
                "蚜蛾蝉蛹,龟卵翼蝗,蚊蝇鼠蚁,蛇蝎鳝蟒。",
                "蜈蚣毒腺,蟋蟀蹬闯,鹿狈狐狸,熊豹豺狼。",
                "猿啼猴吱,鸵孵獭躺,雏猩攀梢,雌牡匿冈。",
                "砂舟骆驼,迅捷羚羊。"};
        String str = strArr[(int)(Math.random()*62)];
        return str;
    }

    public static String getRandomNum(int length){
        //1.  定义一个字符串(A-Z,a-z,0-9)即62个数字字母;
        String str="1234567890";
        //2.  由Random生成随机数
        Random random=new Random();
        StringBuffer sb=new StringBuffer();
        //3.  长度为几就循环几次
        for(int i=0; i<length; ++i){
            //从10个的数字中选择
            int number=random.nextInt(10);
            //将产生的数字通过length次承载到sb中
            sb.append(str.charAt(number));
        }
        //将承载的字符转换成字符串
        return sb.toString();
    }


    public static void main(String[] args) {
        //这里的32是生成32位随机码,根据你的需求,自定义
        String random1 = getRandomString(32);
        System.out.println(random1);
        String random2 = getRandomNum(32);
        System.out.println(random2);
    }

}

(7)启动类

import com.lhf.springboot.scheduled.ScheduledExecutorServiceDemo;
import com.lhf.springboot.springTask.SpringTaskDemo;
import com.lhf.springboot.timer.TimerDemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling   //注解开启对定时任务的支持
public class SpringBootTaskJobApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootTaskJobApplication.class, args);

        TimerDemo timerDemo = new TimerDemo();
        timerDemo.timerJob();

        ScheduledExecutorServiceDemo sch = new ScheduledExecutorServiceDemo();
        sch.scheduledJob();

        SpringTaskDemo st = new SpringTaskDemo();
        st.scheduledCron();
        st.scheduledFixedRate();
        st.scheduledFixedDelay();

    }

}

三、启动项目,运行效果如下:

https://img1.sycdn.imooc.com//5e15ef160001546517580792.jpg

https://img1.sycdn.imooc.com//5e15ef3f0001a5f817500560.jpg

发文不易,如果对你有帮助,请点个赞,感谢你的支持!有问题可以留言!


结束语:人生伟业的建立,不在能知,乃在能行。能行需要坚持,并且认准目标,勇敢前行!


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
1.5万
获赞与收藏
8507

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消