一、 Scheduled 定时任务器
Scheduled 定时任务器:是 Spring3.0 以后自带的一个定时任务器。
1 在 pom 文件中添加 Scheduled 的坐标
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
</parent>
<groupId>com.kennosaur</groupId>
<artifactId>springboot-scheduled</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- springBoot的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springBoot的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 添加Scheduled坐标 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
</dependencies>
</project>
2 编写定时任务类-----@Scheduled(cron="0/2 * * * * ?")
package com.kennosaur.scheduled;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* Scheduled定时任务
*
*
*/
@Component
public class ScheduledDemo {
/**
* 定时任务方法
* @Scheduled:设置定时任务
* cron属性:cron表达式。定时任务触发是时间的一个字符串表达形式
*/
@Scheduled(cron="0/2 * * * * ?")
public void scheduledMethod(){
System.out.println("定时器被触发"+new Date());
}
}
3 在启动类中开启定时任务的使用--------@EnableScheduling
package com.kennosaur;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
*
*Scheduled
*
*/
@SpringBootApplication
@EnableScheduling
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
4 cron 表达式讲解
Cron 表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功能,细说如下:
二、 Spring Boot 整合 Quartz 定时任务框架
1 Quartz 的介绍以及 Quartz 的使用思路
2 Quartz 的基本使用方式
2.1创建项目----普通jar的maven工程即可
2.2修改 pom 文件添加 Quartz 的坐标
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
2.3创建 Job 类
package com.kennosaur.quartz;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* 定义任务类
* @author Administrator
*
*/
public class QuartzDemo implements Job {
/**
* 任务被触发时所执行的方法
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Execute...."+new Date());
}
}
2.4编写测试代码
package com.kennosaur.quartz;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class QuartzMain {
public static void main(String[] args) throws Exception {
// 1.创建Job对象:你要做什么事?
JobDetail job = JobBuilder.newJob(QuartzDemo.class).build();
/**
* 简单的trigger触发时间:通过Quartz提供一个方法来完成简单的重复调用 cron
* Trigger:按照Cron的表达式来给定触发的时间
*/
// 2.创建Trigger对象:在什么时间做?
// Trigger trigger = TriggerBuilder.newTrigger()
// .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever())
// .build();
Trigger trigger = TriggerBuilder.newTrigger()
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
.build();
// 3.创建Scheduler对象:在什么时间做什么事?
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.scheduleJob(job, trigger);
//启动
scheduler.start();
}
}
3 .Spring Boot 整合 Quartz 定时框架
3.1修改 pom 文件添加坐标
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
</parent>
<groupId>com.kennosaur</groupId>
<artifactId>springboot-scheduled</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- springBoot的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springBoot的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Quartz坐标 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<!--<version>2.3.2</version>-->
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加Scheduled坐标 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- Sprng tx 坐标 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>
</project>
3.2编写 Quartz 的启动类
package com.kennosaur.config;
import org.quartz.SchedulerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
import com.kennosaur.quartz.QuartzDemo;
/**
* Quartz配置类
*
*
*/
@Configuration
public class QuartzConfig {
/**
* 1.创建Job对象
*/
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean factory = new JobDetailFactoryBean();
//关联我们自己的Job类
factory.setJobClass(QuartzDemo.class);
return factory;
}
/**
* 2.创建Trigger对象
* 简单的Trigger
*/
// @Bean
// public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
// SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
// //关联JobDetail对象
// factory.setJobDetail(jobDetailFactoryBean.getObject());
// //该参数表示一个执行的毫秒数
// factory.setRepeatInterval(2000);
// //重复次数
// factory.setRepeatCount(5);
// return factory;
// }
/**
* Cron Trigger
*/
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
factory.setJobDetail(jobDetailFactoryBean.getObject()); //设置触发时间
factory.setCronExpression("0/2 * * * * ?");
return factory;
}
/**
* 3.创建Scheduler对象
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean){
SchedulerFactoryBean factory = new SchedulerFactoryBean();
//关联trigger
// factory.setTriggers(simpleTriggerFactoryBean.getObject());
factory.setTriggers(cronTriggerFactoryBean.getObject());
return factory;
}
}
3.3修改启动类
package com.kennosaur;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
*
*Scheduled
*
*/
@SpringBootApplication
@EnableScheduling
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
4 Job 类中注入对象
package com.kennosaur.service;
import org.springframework.stereotype.Service;
@Service
public class UsersService {
public void addUsers() {
System.out.println("Add Users....");
}
}
package com.kennosaur.quartz;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import com.kennosaur.service.UsersService;
/**
* 定义任务类
* @author Administrator
*
*/
public class QuartzDemo implements Job {
@Autowired
private UsersService usersService;
/**
* 任务被触发时所执行的方法
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Execute...."+new Date());
this.usersService.addUsers();
}
}
4.1注入时会产生异常--------因为UsersService 在QuartzDemo中没有被注入到springIOC容器中
AdaptableJobFactory中的createJobInstance是通过反射完成实例化的
4.2编写一个 MyAdaptableJobFactory 解决该问题
package com.kennosaur.config;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;
@Component("myAdaptableJobFactory")
public class MyAdaptableJobFactory extends AdaptableJobFactory {
//AutowireCapableBeanFactory 可以将一个对象添加到SpringIOC容器中,并且完成该对象注入
@Autowired
private AutowireCapableBeanFactory autowireCapableBeanFactory;
/**
* 该方法需要将实例化的任务对象手动的添加到springIOC容器中并且完成对象的注入
*/
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object obj = super.createJobInstance(bundle);
//将obj对象添加Spring IOC容器中,并完成注入
this.autowireCapableBeanFactory.autowireBean(obj);
return obj;
}
}
4.3修改 QuartzConfig 类
factory.setJobFactory(myAdaptableJobFactory);
package com.kennosaur.config;
import org.quartz.SchedulerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
import com.kennosaur.quartz.QuartzDemo;
/**
* Quartz配置类
*
*
*/
@Configuration
public class QuartzConfig {
/**
* 1.创建Job对象
*/
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean factory = new JobDetailFactoryBean();
//关联我们自己的Job类
factory.setJobClass(QuartzDemo.class);
return factory;
}
/**
* 2.创建Trigger对象
* 简单的Trigger
*/
// @Bean
// public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
// SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
// //关联JobDetail对象
// factory.setJobDetail(jobDetailFactoryBean.getObject());
// //该参数表示一个执行的毫秒数
// factory.setRepeatInterval(2000);
// //重复次数
// factory.setRepeatCount(5);
// return factory;
// }
/**
* Cron Trigger
*/
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
factory.setJobDetail(jobDetailFactoryBean.getObject()); //设置触发时间
factory.setCronExpression("0/2 * * * * ?");
return factory;
}
/**
* 3.创建Scheduler对象
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean,MyAdaptableJobFactory myAdaptableJobFactory){
SchedulerFactoryBean factory = new SchedulerFactoryBean();
//关联trigger
// factory.setTriggers(simpleTriggerFactoryBean.getObject());
factory.setTriggers(cronTriggerFactoryBean.getObject());
factory.setJobFactory(myAdaptableJobFactory);
return factory;
}
}