SpringBoot实现定时任务的两种方式

定时任务的两种实现方式


@Scheduled

使用@Scheduled非常容易,直接创建一个SpringBoot项目,并且添加web依赖spring-boot-starter-web,项目创建成功后,添加@EnableScheduling注解,开启定时任务:
@SpringBootApplication
@EnableScheduling
public class SpringbootQuartzScheduledApplication {
 public static void main(String[] args) {
         SpringApplication.run(SpringbootQuartzScheduledApplication.class, args);
   }

}

然后配置定时任务:

@Scheduled(fixedRate = 2000)
/*fixedRate表示两次任务开始时间的间隔*/
public void fixedRate(){
    System.out.println("fixRate>>> " +new Date());
}
@Scheduled(fixedDelay = 2000)
/*fixedDelay表示第一次任务结束到第二次任务开始之间的间隔*/
public void fixeDelay(){
     System.out.println("fixedDelay>>>" +new Date());
}
@Scheduled(initialDelay = 2000,fixedDelay = 2000)
/*initialDelay表示任务首次启动的延迟时间*/
public void initialDelay( ){
     System.out.println("initialDelay>>>"+ new Date( ));
}

其次@Scheduled也支持cron表达式,它的格式如下:

[秒][分][小时][日][月][周][年]
序号说明是否必填允许填写的值允许的通配符
10-59- * /
20-59- * /
30-23- * /
41-31- * / ? L W
51-12 or JAN-DEC- * /
61-7 or sun-SAT- * / ? L ##
71970-2099- * /
通配符含义
? 表示不指定值,即不关心某个字段的取值使用,月份中的日期和星期可能产生冲突,在配置时最好一个为?
* 表示所有值,在秒字段上设置*,表示每一秒都会触发
, 用来分开多个值,在周字段上设置"MON,WED,FRI"表示周一,周三,周五触发
- 表示区间,秒上设置"10-12"表示10,11,12秒会触发
/ 表示递增触发,秒上设置"5/15"表示从5秒开始,每隔15秒触发一次
## 序号,例如周字段上设置"6##3"表示在每月的第三个周六,且可以使用英文(不区分大小写)
L 表示最后的意思,在日字段上设置表示当月的最后一天。在周字段上设置"6L"表示"本月最后一个星期五"
W 表示离指定日期的最近工作日(周一至周五),例如在日字段上设置"15W"表示距离每月15号最近的工作日触发,例如设置员工发工资的日期。
LW一起组合使用,如果在日字段上设置"LW",则表示在本月的最后一个工作日触发。
@Scheduled(cron = "0/5 * * * * *")
//表示该方法每5秒执行一次
public voud cron(){
   System.out.println("date:"+new Date());
}

接下来我们看如何用第三方框架Quartz来实现


业务简单的时候可以用@Scheduled注解来解决任务,否则大部分情况下可能都是使用Quartz来做定时任务的,使用Quartz的步骤:

一、添加pom依赖

二、在项目主启动类上开启定时任务的注解@EnableScheduling

@SpringBootApplication
@EnableScheduling
public class SpringbootQuartzScheduledApplication {

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

}

三、Quatrz使用过程中有两个概念,一个是jobDetail,另一个是触发器,要定义jobDetail首先要定义job,这里有两种方式来定义job

@Component
public class MyJob1{
    public void sayHello( ){
      System.out.println("myjob>>>"+new Date());
    }
}

它的缺点是无法传参。

第二种方式则是集成QuartzJobBean并实现默认的方法
创建如下三个类,HelloService是用来模拟提供服务的类

public class HelloService{
    public void sayHello(){
        System.out.println("hello service>>>"+System.currentTimeMillis());
    }
}

MyJob2继承QuartzJobBean
public class Myjob2 extends QuartzJobBean {

    private HelloService helloService;
    public HelloService getHelloService(){
        return helloService;
    }
    public void setHelloService(HelloService helloService){
        this.helloService = helloService;
    }

    @Override
    protected  void executeInternal(JobExecutionContext jobExecutionContext)
    {
        helloService.sayHello();
    }


}
与第一种方式相比,这种方式支持传参,任务启动时,executeInternal方法将会被执行。job创建好之后接下来创建类,配置JobDetail和Trigger触发器,如下:
@Configuration
public class QuartzConfig {
    @Bean
    MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() {
        MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
        bean.setTargetBeanName("myjob1");
        bean.setTargetMethod("sayHello");
        return bean;
    }

    @Bean
    JobDetailFactoryBean jobDetailFactoryBean() {
        JobDetailFactoryBean bean = new JobDetailFactoryBean();
        bean.setJobClass(Myjob2.class);
        JobDataMap map = new JobDataMap();
        map.put("helloService",helloService());
        bean.setJobDataMap(map);
        return bean;
    }

    /*设置触发器SimpleTrigger*/
    @Bean
    SimpleTriggerFactoryBean simpleTriggerFactoryBean() {
        SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
        bean.setStartTime(new Date());
        //设置执行次数
        bean.setRepeatCount(5);
         bean.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());	
		 /*MyJob每3秒执行一次*/
        bean.setRepeatInterval(3000);
        return bean;
    }

    /*设置触发器CronTrigger*/
    @Bean
    CronTriggerFactoryBean cronTrigger() {
        CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
       /*设置每10秒执行一次*/
        bean.setCronExpression("0/10 * * * * ?");
        bean.setJobDetail(jobDetailFactoryBean().getObject());
        return bean;
    }

    @Bean
    SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        bean.setTriggers(cronTrigger().getObject(), simpleTriggerFactoryBean().getObject());
        return bean;
    }

    @Bean
    HelloService helloService() {
        return new HelloService();
    }
}

运行结果如图:

关于这个配置类的说明如下:

1.JobDetail的配置方式有两种:MethodInvokingJobDetailFactoryBean和JobDetailFactoryBean。

2.使用MethodInvokingJobDetailFactoryBean 可以配置目标Bean的名字和目标方法的名字,但是不支持传参

3.使用JobDetailFactoryBean可以配置JobDetail,任务类继承自QuartzJobBean,这种方式支持传参,参数封装在JobDataMap中传递。

4.Trigger是指触发器,Quartz中定义了多个触发器,上面代码使用了其中两种,SimpleTrigger和CronTrigger。

5.SimpleTrigger有点类似于前面说的@Scheduled的基本用法。

6.CronTrigger则有点类似于@Scheduled中cron表达式的用法

配置好以后就可以直接运行主启动类,里面定义的定时任务就会按照要求执行

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值