什么是定时任务?
定时任务是企业级开发中最常见的功能之一,如定时统计订单数量、数据库备份、定时发送短信和邮件、定时统计博客访问量等等
@Scheduled
简单的定时任务可以通过 Spring 中提供的 @Scheduled 注解来实现
@Scheduled 是由 Spring 提供的定时任务注解,使用方便,配置简单,可以解决工作中大部分的定时任务需求,使用方式如下:
添加依赖
只需添加 web 依赖即可
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
编写定时任务
package com.example.demo.config;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MySchedule {
/**
* 表示在当前任务执行结束 1s 后开启另一个任务
*/
@Scheduled(fixedDelay = 1000)
public void fixedDelay() {
System.out.println("fixedDelay : " + new Date());
}
/**
* 表示在当前任务执行结束 2s 后开启另一个定时任务
*/
@Scheduled(fixedRate = 2000)
public void fixedRate() {
System.out.println("fixedRate : " + new Date());
}
/**
* initialDelay = 1000 表示首次执行的延迟时间
*/
@Scheduled(initialDelay = 1000,fixedRate = 2000)
public void initialDelay() {
System.out.println("initialDelay : " + new Date());
}
/**
* cron = "0 * * * * ?" 表示该定时任务每分钟执行一次
*/
@Scheduled(cron = "0 * * * * ?")
public void cron() {
System.out.println("cron : " + new Date());
}
}
开启定时任务
开启定时任务只需要在启动类加上 @EnableScheduling 注解即可
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling // 开启定时任务的注解
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class,args);
}
}
输出:
Quartz
什么是 Quartz ?
Quartz 是一个功能丰富的开源作业调度库,它由 Java 编写而成,可以继承在任何 Java 的应用程序之中,包括 Java SE 和 Java EE 等等,使用 Quartz 可以创建简单或者复杂的执行计划,它支持数据库、集群、插件以及邮件,并且支持 cron 表达式,具有极高的灵活性。SpringBoot 中继承了 Quartz 和 Spring 中集成了 Quartz 比较类似,主要提供了三个 Bean:JobDetail、Trigger 以及 SchedulerFactory
添加依赖
添加 SpringBoot 整合 Quartz 的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
创建任务
这里创建两个任务
package com.example.demo.config;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class FirstDemo {
public void sayHello() {
System.out.println("FirstDemo start at : " + new Date());
}
}
FirstDemo 是一个普通的 JavaBean,如果是普通的 JavaBean,那么可以先添加 @Component 注解将其注册到 Spring 容器中。
package com.example.demo.config;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.Date;
public class SecondDemo extends QuartzJobBean {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("hello : " + name + " : " + new Date());
}
}
SecondDemo 也可以继承抽象类 QuartzJobBean,如果继承 QuartzJobBean,则需要实现该类中的 executeInternal 方法,该方法在任务调用时使用
配置类
package com.example.demo.config;
import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.SimpleTrigger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.*;
@Configuration
public class QuartzConfig {
/**
* JobDetail 的配置方式有两种:
* 第一种方式是通过 MethodInvokingJobDetailFactoryBean 类配置 JobDetail,
* 只需要指定 Job 的实例名和要调用的方法即可,注册这种方式无法在创建 JobDetail 时传递参数
*
* 第二种方式是通过 JobDetailFactoryBean 来实现的,这种方式只需要指定 JobClass 即可,然后通过
* JobDataMap 传递参数到 Job 中,Job 中只需要提供属性名,并且提供一个相应的 set 方法即可接收到参数
* @return
*/
@Bean
public MethodInvokingJobDetailFactoryBean jobDetailFactoryBean() {
MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
bean.setTargetBeanName("firstDemo");
bean.setTargetMethod("sayHello");
return bean;
}
@Bean
public JobDetailFactoryBean jobDetailFactoryBean2() {
JobDetailFactoryBean bean = new JobDetailFactoryBean();
bean.setJobClass(SecondDemo.class);
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("name","John");
bean.setJobDataMap(jobDataMap);
bean.setDurability(true);
return bean;
}
/**
* Trigger 有多种不同的实现,这里分别使用 SimpleTrigger 和 CronTrigger
* @return
*/
/**
* 在 SimpleTriggerFactoryBean 对象中,首先设置 JobDetail,然后通过 setRepeatCount 配置任务
* 循环次数,setStartDelay 配置任务启动延迟时间,setRepeatInterval 配置任务的时间间隔
* @return
*/
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean() {
SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
bean.setJobDetail(jobDetailFactoryBean().getObject());
bean.setRepeatCount(3);
bean.setStartDelay(1000);
bean.setRepeatInterval(2000);
return bean;
}
/**
* 在 CronTriggerFactoryBean 对象中,则主要配置 JobDetail 和 Cron 表达式
* @return
*/
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBean() {
CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
bean.setJobDetail(jobDetailFactoryBean2().getObject());
bean.setCronExpression("* * * * * ?");
return bean;
}
/**
* 通过 SchedulerFactoryBean 创建 SchedulerFactory,然后配置 Trigger
* @return
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
SimpleTrigger simpleTrigger = simpleTriggerFactoryBean().getObject();
CronTrigger cronTrigger = cronTriggerFactoryBean().getObject();
bean.setTriggers(simpleTrigger,cronTrigger);
return bean;
}
}
启动定时任务
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class,args);
}
}
输出:
转载:https://blog.csdn.net/Woo_home/article/details/104226255