前言
定时任务就是指定某个时间去执行任务或者代码,SpringBoot中有一个注解@Schedule或者第三方工具quartz,或者TimerTask(java.util)。基本上是通过线程—然后sleep,线程池中的ScheduledExecutorService。
定时任务的实现方式
使用Thread
package com.ssy.demo;
public class Schedule {
public static void main(String[] args) {
new Thread(()->{
int count = 1;
while (true){
try {
Thread.sleep(1000L);
System.out.println("定时任务开始执行了······" + (count++));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
运行结果
使用TimerTask
TimerTask其实和Thread差不多
package com.ssy.demo;
import java.util.Timer;
import java.util.TimerTask;
public class Schedule {
static int count = 1;
public static void main(String[] args) {
TimerTask schedule = new TimerTask() {
@Override
public void run() {
try{
Thread.sleep(1000L);
System.out.println("TimerTask定时任务 调度中······" + (count++));
} catch (InterruptedException e){
e.printStackTrace();
}
}
};
//设置任务调度规则
Timer timer = new Timer();
long delay = 6000;//使用首次延时 毫秒数
long period = 1;//任务间隔时间 毫秒数
/*
* schedule 和 scheduleAtFixedRate 区别:
* 可将schedule理解为scheduleAtFixedDelay,
* 两者主要区别在于delay和rate
* 1、schedule,如果第一次执行被延时(delay),
* 随后的任务执行时间将以上一次任务实际执行完成的时间为准
* 2、scheduleAtFixedRate,如果第一次执行被延时(delay),
* 随后的任务执行时间将以上一次任务开始执行的时间为准(需考虑同步)
*
* 参数:1、任务体 2、延时时间(可以指定执行日期)3、任务执行间隔时间
*/
// timer.schedule(schedule, 0, 1000 * 3);
timer.scheduleAtFixedRate(schedule,delay,period);
//总体而言和Thread差不多
}
}
运行结果
使用ScheduledExecutorService
package com.ssy.demo;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Schedule {
static int count = 1;
public static void main(String[] args) {
Runnable runnable = ()->{
while (true){
System.out.println("使用线程池的任务调度······" + (count++));
}
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable,1000,1000, TimeUnit.MILLISECONDS);
}
}
运行结果
SpringBoot中使用@Schedule注解
在SpringBoot中使用注解的方式很方便
1.首先加入依赖
<?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>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.3.2.RELEASE</version>
</parent>
<groupId>com.ssy</groupId>
<artifactId>juc</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
2.创建启动类并添加启动任务调度的注解
package com.ssy.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @ClassName ScheduleApp
* @Description ScheduleApp
* @Author ssy
* @Date 2023-06-06 12:34:04
*/
@SpringBootApplication
@EnableScheduling//开启任务调度
public class ScheduleApp {
public static void main(String[] args) {
SpringApplication.run(ScheduleApp.class,args);
}
}
3.写任务类并加上任务规则交给Spring来管理
package com.ssy.demo.task;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* @ClassName MyTask
* @Description MyTask
* @Author ssy
* @Date 2023-06-06 12:36:47
*/
@Component//交给Spring容器管理
public class MyTask {
//调度的规则
@Scheduled(cron = "0/2 * * * * ?")
public void say(){
System.out.println("每2s执行一次" + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
}
}
运行结果
使用Quartz
但是一般情况下大公司不会使用Quartz,因为真的不方便管理呀,这是个很头疼的问题。
Quartz官网:Quartz EnterPrice Job Scheduler
Quartz的组成
1.任务Job(你要明白你想要做啥子事情)
2.触发器Trigger(啥子时间点去做这件事情)
3.调度器Scheduler(什么时候需要做什么事)
简单的Quartz测试Demo
使用Quartz首先需要引入Quartz的依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<!--要加上这个日志,不然是有警告的,而且还需要日志的实现类-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.7</version>
<scope>compile</scope>
</dependency>
没有日志的依赖和实现会有警告
注意不要在一个文件中写多个类对于Quartz的任务调度,否则会无法得到具体结果。
实现Job的类
package com.ssy.demo;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @ClassName Task
* @Description Task
* @Author Ssy
* @Date 2023-06-06 12:14:50
*/
public class Task implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("Quartz任务调度···" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
主函数运行的类
package com.ssy.demo;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
public class Schedule {
public static void main(String[] args) throws SchedulerException {
test1();
}
public static void test1() throws SchedulerException {
//1、调度器(Schedular),从工厂中获取调度实例(默认:实例化new StdSchedulerFactory();)
Scheduler scheduler= StdSchedulerFactory.getDefaultScheduler();
//2、任务实例(JobDetail)
JobDetail jobDetail= JobBuilder.newJob(Task.class) //加载任务类,与Task完成绑定,要求Task实现Job接口
.withDescription("Quartz定时任务")//描述
.withIdentity("job1","group1") //参数1:任务的名称(唯一实例);参数2:任务组的名称
.build();
//3、触发器(Trigger)
Trigger trigger= TriggerBuilder.newTrigger()
.withIdentity("trigger1","group1") //参数1:触发器的名称(唯一实例);参数2:触发器组的名称
.startNow() //马上启动触发器
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)) //每5秒执行一次
.build();
//让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
scheduler.scheduleJob(jobDetail,trigger);
//启动
scheduler.start();
}
public static void test2() throws SchedulerException {
StdSchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
JobDetail job = JobBuilder.newJob(Task.class)
.withDescription("任务猫叔")
.withIdentity("taskName", "taskGroup")
.build();
CronTrigger trigger = TriggerBuilder.newTrigger()
.withDescription("触发器描述")
.withIdentity("triggerName", "triggerGroup")
.startAt(new Date(System.currentTimeMillis() + 3 * 1000L))
//.withSchedule(SimpleScheduleBuilder.simpleSchedule())
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))//表示每两秒执行一次
//CronExpression参考网址:cron.qqe2.com
.build();
scheduler.scheduleJob(job,trigger);
scheduler.start();
}
}
运行结果
SpringBoot整合Quartz
需要实现Quartz的接口,只不过不想SpringBoot那样使用@Scheduled注解了,而是改为配置的方式:配置自定义的任务Job,关联自定义的JobDetail、SimpleTrigger、设置自定义的Schedule
1.pom.xml
<?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>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.3.2.RELEASE</version>
</parent>
<groupId>com.ssy</groupId>
<artifactId>juc</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
</dependencies>
</project>
2.自定义的任务
package com.ssy.demo.task;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* @ClassName QuartzTask
* @Description QuartzTask
* @Author ssy
* @Date 2023-06-06 14:02:47
*/
public class QuartzTask implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println(LocalTime.now().format(DateTimeFormatter.ofPattern("HH时mm分ss秒")));
}
}
3.配置Quartz的Config
package com.ssy.demo.config;
import com.ssy.demo.task.QuartzTask;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
/**
* @ClassName QuartzConfig
* @Description QuartzConfig
* @Author ssy
* @Date 2023-06-06 14:02:16
*/
@Configuration
public class QuartzConfig {
//设置自己的Job任务
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
//设置自定义的任务
factoryBean.setJobClass(QuartzTask.class);
return factoryBean;
}
//设置触发器Trigger对象
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
//设置自定义的JobDetail对象
factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
//设置调度规则
//设置间隔执行的时间为2s每次
factoryBean.setRepeatInterval(2000L);
//设置触发的次数为5次
factoryBean.setRepeatCount(5);
return factoryBean;
}
//设置调度器
@Bean
public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean){
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
//设置自定义的trigger
factoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
return factoryBean;
}
}
4.主启动类还是需要添加@EnableScheduling注解
package com.ssy.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class ScheduleApp {
public static void main(String[] args) {
SpringApplication.run(ScheduleApp.class,args);
}
}
运行结果
SpringBoot关联Mybatis整合Quartz实现JDBC定时调度操作
1.准备数据库
/*
Navicat MySQL Data Transfer
Source Server : ssy
Source Server Type : MySQL
Source Server Version : 80027 (8.0.27)
Source Host : localhost:3306
Source Schema : demo
Target Server Type : MySQL
Target Server Version : 80027 (8.0.27)
File Encoding : 65001
Date: 06/06/2023 16:24:32
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`password` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Procedure structure for cbrbpro
-- ----------------------------
DROP PROCEDURE IF EXISTS `cbrbpro`;
delimiter ;;
CREATE PROCEDURE `cbrbpro`()
BEGIN
DECLARE id1 BIGINT DEFAULT 1172190356676366336;
DECLARE batch_id1 VARCHAR(40) DEFAULT '';
DECLARE id2 VARCHAR(40) DEFAULT '';
DECLARE ts BIGINT DEFAULT 923995767320230831;
WHILE ts<923995767320231331
DO
SET batch_id1 = CAST(ts as CHAR);
SET id2 = CAST(id1 as CHAR);
INSERT INTO `cw_bd_record_batch`(`ID`,`PK_SCENARIOSCHEME`,`INITIATE_USE`,`INITIATE_TIME`,`PROJECT_CODE`,`PROJECT_NAME`,`BATCH_NO`,`TRADECODE`,`PREPAREDATE`,`INST_ID`,`SIGN_TYPE`,`FATL_REASON`,`PARAM_TYPE`,`USE_STATE`,`CREATE_USER`,`CREATE_TIME`,`UPDATE_USER`,`UPDATE_TIME`,`REMARK`,`strike_type`,`pk_system`)
VALUES(id2, '8700518079451217921','hanjia','2023-02-06 16:21:41','2021Z1837','融先估值分级基金测试sxz-基准账',batch_id1,'CJ2008','2021-12-24 00:00:0',NULL,'0','','1','1','ADMIN','2023-02-06 16:21:41',NULL,'2023-04-19 18:33:17',NULL,'1','06');
SET id1 = id1 + 1;
set ts = ts + 1;
END WHILE;
COMMIT;
END
;;
delimiter ;
-- ----------------------------
-- Procedure structure for test
-- ----------------------------
DROP PROCEDURE IF EXISTS `test`;
delimiter ;;
CREATE PROCEDURE `test`()
BEGIN
DECLARE i BIGINT DEFAULT 20000831;
DECLARE j BIGINT DEFAULT 500;
DECLARE tid VARCHAR(40) DEFAULT '';
DECLARE bid VARCHAR(40) DEFAULT '';
DECLARE sid VARCHAR(40) DEFAULT '';
DECLARE usa VARCHAR(40) DEFAULT '8';
DECLARE ts BIGINT DEFAULT 1;
WHILE ts<500
DO
SET tid = CAST(i as CHAR);
SET bid = CAST(j as CHAR);
SET sid = CAST(j as CHAR);
insert into tek(id,batch_id,serial_id,use_state) values(tid,bid,sid,usa);
SET i = i+10+round(rand()*10,0);
SET j = j-1;
END WHILE;
COMMIT;
END
;;
delimiter ;
SET FOREIGN_KEY_CHECKS = 1;
2.pom依赖
<?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>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.3.2.RELEASE</version>
</parent>
<groupId>com.ssy</groupId>
<artifactId>juc</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
3.yml配置文件
spring:
application:
name: quartz-to-mysql
datasource:
druid:
db-type: mysql
username: root
password: 12345
url: jdbc:mysql://localhost:3306/demo?useUnicode=true&charaterEncoding=UTF-8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
type-aliases-package: com.ssy.demo.entity
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
server:
port: 9001
4.主启动类加注解@EnableScheduling
package com.ssy.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class ScheduleApp {
public static void main(String[] args) {
SpringApplication.run(ScheduleApp.class,args);
}
}
5.系列JDBC操作
5.1 实体类
package com.ssy.demo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @ClassName User
* @Description User
* @Author ssy
* @Date 2023-06-06 14:38:41
*/
@TableName("`user`")
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
public class User implements Serializable {
private static final long serializerId = 20233202L;
@TableId(type = IdType.AUTO)
private Integer id;
@TableField("username")
private String username;
@TableField("password")
private String password;
}
5.2 java的mapper映射层
package com.ssy.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ssy.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @ClassName UserMapper
* @Description UserMapper
* @Author ssy
* @Date 2023-06-06 14:41:50
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
Integer add(@Param("user") User user);
}
5.3 xml的mapper映射SQL
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssy.demo.mapper.UserMapper">
<insert id="add">
insert into `user`(username,password) values(#{user.username},#{user.password})
</insert>
</mapper>
5.4 service层
package com.ssy.demo.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ssy.demo.entity.User;
import org.apache.ibatis.annotations.Param;
/**
* @ClassName UserService
* @Description UserService
* @Author ssy
* @Date 2023-06-06 14:45:36
*/
public interface UserService extends IService<User> {
void insert(User user);
}
5.5 service的实现impl
package com.ssy.demo.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ssy.demo.entity.User;
import com.ssy.demo.mapper.UserMapper;
import com.ssy.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* @ClassName UserServiceImpl
* @Description UserServiceImpl
* @Author ssy
* @Date 2023-06-06 14:47:21
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
private UserMapper userMapper;
@Transactional(rollbackFor = Exception.class)
@Override
public void insert(User user) {
int affectedRows = userMapper.insert(user);
if(affectedRows>0)
System.out.println(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + "\t插入成功");
else
System.out.println(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + "\t插入失败");
}
}
5.6 自定义的Quartz任务操作JDBC
package com.ssy.demo.task;
import com.ssy.demo.entity.User;
import com.ssy.demo.service.UserService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @ClassName QuartzTask
* @Description QuartzTask
* @Author ssy
* @Date 2023-06-06 14:02:47
*/
public class JdbcTask implements Job {
//此处使用了自动注入,那么必须交给IOC容器管理,切记不能在该类上加注解交给IOC容器,一定手动写一个适配工厂放到IOC中
//Spring IOC的生命周期☆
@Autowired
private UserService userService;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
User user = new User();
user.setUsername("好好而活").setPassword("lover");
userService.insert(user);
}
}
5.7 将操作JDBC的任务手动交给IOC并完成注入
package com.ssy.demo.factory;
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;
/**
* @ClassName IOCJobFactory
* @Description IOCJobFactory
* @Author ssy
* @Date 2023-06-06 14:59:26
*/
//该类的作用是解决JdbcTask类中的自动注入@Autowried问题的
//因为这个类并没有交给IOC容器管理,就使用了次注解
//所以在此处手动注入,不然是无法完成代理操作的
//但是此类要交给IOC,不然就管理不到了
//继承AdaptableJobFactory重写creteJobInstance方法即可
//因为是对定时任务注入所以继承的是AdaptableJobFactory而非其它的
@Component
public class IOCJobFactory extends AdaptableJobFactory {
//AutowireCapableBeanFactory可以添加对象到Spring IOC容器中并完成依赖注入
@Autowired
private AutowireCapableBeanFactory autowireCapableBeanFactory;
//手动添加对象到IOC + 完成依赖注入
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object obj = super.createJobInstance(bundle);
//添加到IOC并完成注入
autowireCapableBeanFactory.autowireBean(obj);
return obj;
}
}
5.8 Quartz的任务调度配置(JobDetail、SimpleTrigger、Scheduler)
package com.ssy.demo.config;
import com.ssy.demo.factory.IOCJobFactory;
import com.ssy.demo.task.JdbcTask;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
/**
* @ClassName QuartzConfig
* @Description QuartzConfig
* @Author ssy
* @Date 2023-06-06 14:02:16
*/
@Configuration
public class QuartzConfig {
//设置自己的Job任务
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
//设置自定义的任务
factoryBean.setJobClass(JdbcTask.class);//注意JdbcTask类是没有自动交给IOC管理的,所以要手动设置
return factoryBean;
}
//设置触发器Trigger对象
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
//设置自定义的JobDetail对象
factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
//设置调度规则
//设置间隔执行的时间为2s每次
factoryBean.setRepeatInterval(2000L);
//设置触发的次数为5次
factoryBean.setRepeatCount(5);
return factoryBean;
}
//设置调度器
@Bean
//setJobFactory可传参可自动注入,二选一
public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean, IOCJobFactory iocJobFactory){
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
//设置自定义的trigger
factoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
factoryBean.setJobFactory(iocJobFactory);
return factoryBean;
}
}
运行结果
XXL-JOB
XXL-JOB是一个比较受业内欢迎的定时调度任务的平台,由于官方介绍比较详细而且开源,本着尊重原创的理念,小编就不在这里赘述了,请移驾官网:https://www.xuxueli.com/xxl-job/。小编也比较支持XXL-JOB。