定时器:
在一定时间内执行的所触发的方法。使用场景也挺多的,如一个系统的日志需要定期删除。
Schedule:
定时任务器:是spirng3.0以后自带的一个定时任务器。
使用:
第一步:在pom文件中添加schedule的坐标
<!--spring-boot的核心启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--添加Schedule定时器-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!--开启test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
第二步:添加ScheduleDemo测试类
@Component
public class ScheduleDemo {
/**
* 定时任务
* @Scheduled 设置定时任务
* cron 需要cron的表达式 是一个定时触发的字符串的表达式
*
* cron表达式
* 分6字表达式和7字表达式
*
* second minute hour day month week 6字表达式
* second minute hour day month week year 7字表达式
*
* second 区间 [0,59]
* minute 区间 [0,59]
* hour 区间 [0,23]
* day 区间 [1,31]
* month 区间 [1,12]
* week 区间 [1,7],注意 这里星期一代表7,星期填为6,外国的第一天是从7开始
* year 区间[1950,2099]
*
* 符号的作用:
* 1.星号(*):可用在所有字段中,代表对应时间的每一刻,eg:*在分钟字段中代表,每一分钟执行
* 2.问号(?):占位符作用,通常指定无意义的值
* 3.减号(-):代表一个区间,表示在一个时间范围之内 10-12
* 4.逗号(,) 代表在一个范围内,1,4,5,6 在此序列内
* 5.斜杠(/):x/y代表一个等长序列,x为起始值,y为递增步数,0/15,若在秒中出现则是每隔15秒执行一次
* 等。
*
* eg:@Scheduled(cron = "0 0 1 1 1,4,7,10 ?")//每个季度的一月一号1点执行
*
*/
@Scheduled(cron = "0/2 * * * * ?")
public void scheduleMethod(){
System.out.println("触发 "+ new Date());
}
}
第三步:在启动类中开启定时任务
@SpringBootApplication
@EnableScheduling//开启schedule定时任务
public class App extends SpringBootServletInitializer {
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(App.class);
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
Quartz:
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。
使用:
1.Job-任务 你要做什么事情
2.Trigger-触发器 什么时候去做
3.Schedule 任务调度 你什么时候去做什么事情.
第一步:在pom文件中添加Quartz的坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.whut.schedule</groupId>
<artifactId>spring-boot-schedule</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--spring-boot的核心启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--添加Schedule定时器-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!--开启test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--Quartz的坐标-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!--Spring tx 坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>
</project>
第二步:编写QuartzDemo任务类
/**
* 定义任务类
* 整合SpringBoot
*/
@Component
public class QuartzDemo implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("execute " + new Date());
}
}
第三步:配置Quartz,编写QuartzConfig类来配置Quartz
@Configuration
public class QuartzConfig {
/**
* 创建Job对象
*要去做什么
*/
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean factory = new JobDetailFactoryBean();
factory.setJobClass(QuartzDemo.class);
return factory;
}
/**
* 创建Trigger对象
* 什么时候去做
* 创建的简单的Trigger
*/
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
//整合Job 关联Job
//
factory.setJobDetail(jobDetailFactoryBean.getObject());
//repeatInterval 执行的毫秒数
factory.setRepeatInterval(2000);
//设置重复次数
factory.setRepeatCount(5);
return factory;
}
/**
* CronTrigger
*/
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
//关联Job
factory.setJobDetail(jobDetailFactoryBean.getObject());
//设置CronTrigger
factory.setCronExpression("0/2 * * * * ?");
return factory;
}
/**
* 创建Scheduler对象
* 在什么时间去做什么事情
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean(
SimpleTriggerFactoryBean simpleTriggerFactoryBean,
MyAdaptableJobFactory myAdaptableJobFactory
){
SchedulerFactoryBean factory = new SchedulerFactoryBean();
//关联Trigger 可以关联CronTrigger
factory.setTriggers(simpleTriggerFactoryBean.getObject());
return factory;
}
}
经过上述操作即可完成定时任务的整合。
Quartz:Quartz整合业务逻辑对象的注入
上述都是在测试是否能正常在特定时间内执行定时触发任务,没有关联业务逻辑代码。
给定场景:在特定时间内添加用户,这里简单化处理
一:新建测试服务类UserService
@Service
public class UserService {
public void addUser(){
System.out.println("add user :" + new Date());
}
}
二:在任务类QuartzDemo中注入该任务类
/**
* 定义任务类
* 整合SpringBoot
*/
@Component
public class QuartzDemo implements Job {
@Autowired
private UserService userService;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("execute " + new Date());
userService.addUser();
}
}
当运行该项目时候会抛出这样的错误:
提示我们的UserService 没有注入进去。
原因:
QuartzDemo 对象的实例化完全交给了JobDetailFactoryBean来完成 * 实际上实例化采用反射机制来实现 * QuartzDemo 的实例化没有经过Spring的处理 * Spring注入需要注入对象和被注入对象全部都存在与Spring IOC容器中
这里需要我们手动将对象注入到SpingIOC容器中.
三:添加MyAdaptableJobFactory来手动注入
@Component("myAdaptableJobFactory")
public class MyAdaptableJobFactory extends AdaptableJobFactory {
//将一个对象加入到SpringIOC容器中,并且完成对象注入
@Autowired
private AutowireCapableBeanFactory autowireCapableBeanFactory;
/**
* 将实列化的任务对象手动加入到SpringIOC容器中,并且完成对象注入
* @param bundle
* @return
* @throws Exception
*/
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object object = super.createJobInstance(bundle);
//将object添加到SpringIOC容器中,并完成对象的注入
this.autowireCapableBeanFactory.autowireBean(object);
return object;
}
}
四:修改QuartzConfig来完成配置
@Configuration
public class QuartzConfig {
/**
* 创建Job对象
*要去做什么
*/
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean factory = new JobDetailFactoryBean();
/**
* QuartzDemo 对象的实例化完全交给了JobDetailFactoryBean来完成
* 实际上实例化采用反射机制来实现
* QuartzDemo 的实例化没有经过Spring的处理
* Spring注入需要注入对象和被注入对象全部都存在与Spring IOC容器中
*/
factory.setJobClass(QuartzDemo.class);
return factory;
}
/**
* 创建Trigger对象
* 什么时候去做
* 创建的简单的Trigger
*/
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
//整合Job 关联Job
//
factory.setJobDetail(jobDetailFactoryBean.getObject());
//repeatInterval 执行的毫秒数
factory.setRepeatInterval(2000);
//设置重复次数
factory.setRepeatCount(5);
return factory;
}
/**
* CronTrigger
*/
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
//关联Job
factory.setJobDetail(jobDetailFactoryBean.getObject());
//设置CronTrigger
factory.setCronExpression("0/2 * * * * ?");
return factory;
}
/**
* 创建Scheduler对象
* 在什么时间去做什么事情
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean(
SimpleTriggerFactoryBean simpleTriggerFactoryBean,
MyAdaptableJobFactory myAdaptableJobFactory
){
SchedulerFactoryBean factory = new SchedulerFactoryBean();
//关联Trigger 可以关联CronTrigger
factory.setTriggers(simpleTriggerFactoryBean.getObject());
//手动注入
//----------------------------------------------------------
factory.setJobFactory(myAdaptableJobFactory);
//----------------------------------------------------------
return factory;
}
}
这样就完成了业务逻辑的定时触发