一、 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;
}
}