Spring boot加Quartz定时器及spring boot自带
Quartz简单触发器
工具类及依赖
pom依赖
数据库相关的依赖暂时注释因为下次才会用到,不注释可能会冲突
下面中间这个依赖是创建spring boot项目的时候可以勾上的
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<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>
我的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 https://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.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.rong</groupId>
<artifactId>quartz01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>quartz01</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-jdbc</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>2.1.4</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>mysql</groupId>-->
<!-- <artifactId>mysql-connector-java</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
项目结构
RamJob
注:这是全部的类代码,下面使用记得把多余部分注释;第二个是后面测多线程的时候用的
package com.rong.quartz01.job;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author Ivan
* @company xxx公司
* @create 2020-12-14 18:37
*/
public class RamJob implements Job {
// @Override
// public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// System.out.println("定时任务具体执行的业务逻辑代码。。");
// JobDataMap jobDataMap=jobExecutionContext.getJobDetail().getJobDataMap();
// System.out.println(jobDataMap.get("name").toString()
// + ":" + jobDataMap.get("level").toString()
// + ":" + jobDataMap.get("job").toString());
// }
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.err.println(format.format(new Date())+" : 基于RAM的quartz调度框架定时任务...");
try {
Thread.sleep(20*1000);
System.out.println("模拟正在处理大数据....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Quartz简单触发器 SimpleTrigger
RamJob
package com.rong.quartz01.job;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author Ivan
* @company xxx公司
* @create 2020-12-14 18:37
*/
public class RamJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("定时任务具体执行的业务逻辑代码。。");
}
}
Demo1
共执行*次,*s执行一次
package com.rong.quartz01.quartz;
import com.rong.quartz01.job.RamJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.JobBuilder.newJob;
/**
* @author Ivan
* @company xxx公司
* @create 2020-12-14 18:30
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
// 调度器
SchedulerFactory schedulerFactory=new StdSchedulerFactory();
Scheduler scheduler=schedulerFactory.getScheduler();
// 作业类
JobDetail jobDetail= newJob(RamJob.class)
.withIdentity("job1","group1")
.withDescription("this is a job1")
.build();
// 触发器
Trigger trigger= (Trigger)TriggerBuilder.newTrigger()
// 执行三次,5s执行一次
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(3,5))
.withIdentity("trigger1","group1")
.withDescription("this is a trigger1")
.build();
// 调度器组装作业类及触发器
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
}
}
运行main方法结果
Quartz表达式触发器CronTirgger
RamJob
package com.rong.quartz01.job;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author Ivan
* @company xxx公司
* @create 2020-12-14 18:37
*/
public class RamJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("定时任务具体执行的业务逻辑代码。。");
}
}
Demo2
0/10 * * * * ?:该表达式是每10秒触发一次
50 56 18 * * ?:18.56.50触发
package com.rong.quartz01.quartz;
import com.rong.quartz01.job.RamJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.JobBuilder.newJob;
/**
* @author Ivan
* @company xxx公司
* @create 2020-12-14 18:30
*/
public class Demo2 {
public static void main(String[] args) throws Exception {
// 调度器
SchedulerFactory schedulerFactory=new StdSchedulerFactory();
Scheduler scheduler=schedulerFactory.getScheduler();
// 作业类
JobDetail jobDetail= newJob(RamJob.class)
.withIdentity("job1","group1")
.withDescription("this is a job1")
.build();
// 触发器 18.56.50触发
Trigger trigger= (Trigger)TriggerBuilder.newTrigger()
.withSchedule(CronScheduleBuilder.cronSchedule("50 56 18 * * ?"))
.withIdentity("trigger1","group1")
.withDescription("this is a trigger1")
.build();
// 调度器组装作业类及触发器
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
}
}
定时main方法运行结果
多次触发运行结果
Quartz触发器参数传递
RamJob
package com.rong.quartz01.job;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author Ivan
* @company xxx公司
* @create 2020-12-14 18:37
*/
public class RamJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("定时任务具体执行的业务逻辑代码。。");
JobDataMap jobDataMap=jobExecutionContext.getJobDetail().getJobDataMap();
System.out.println(jobDataMap.get("name").toString()
+ ":" + jobDataMap.get("level").toString()
+ ":" + jobDataMap.get("job").toString());
}
}
Demo4
package com.rong.quartz01.quartz;
import com.rong.quartz01.job.RamJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.JobBuilder.newJob;
public class Demo4 {
public static void main(String[] args) throws Exception {
// 调度器
SchedulerFactory schedulerFactory=new StdSchedulerFactory();
Scheduler scheduler=schedulerFactory.getScheduler();
// 作业类
JobDetail jobDetail= newJob(RamJob.class)
.withIdentity("job1","group1")
.withDescription("this is a job1")
.build();
JobDataMap jobDataMap=jobDetail.getJobDataMap();
jobDataMap.put("name","小袁");
jobDataMap.put("level","高级");
jobDataMap.put("job","java");
// 触发器
Trigger trigger= (Trigger)TriggerBuilder.newTrigger()
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?"))
.withIdentity("trigger1","group1")
.withDescription("this is a trigger1")
.build();
// 调度器组装作业类及触发器
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
}
}
main方法运行结果
Quartz触发器 VS spring boot自带触发器
spring boot触发器
spring自带的触发器是单线程的触发一次要将整个过程运行完,因为下面交给注解所以一个项目只用一次;结合下面内容你就知道适合用在什么项目中了!
SpringTask触发类
这里设定每十秒执行一次,后面再接一个休眠二十秒;
如果运行出来是每十秒输出一句:这是一个spring task…;每二十秒输出一句:模拟正在处理大数据…;则证明相互之间没有影响,是多线程。
如果三十秒将整个方法过程运行一次表明是单线程:在项目有的方法访问要很长时间,比如下面输出说的处理大数据可能就要点时间,就会影响到触发器的触发周期
package com.rong.quartz01.task;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import sun.misc.Contended;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class SpringTask {
@Scheduled(cron = "0/10 * * * * ?")
public void aaa(){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.err.println(format.format(new Date())+" : 这是一个spring task...");
// 如果30秒才执行一次则为单线程
try {
Thread.sleep(20*1000);
System.out.println("模拟正在处理大数据....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果
我们在项目启动类加上这个注解启动项目
@EnableScheduling
可以看到原本定义没十秒触发一次的输出受休眠20秒影响变成了每三十秒输出一次,整个方法是一条线运行下来的,是单线程!
Quartz触发器
Quartz触发器和spring自带的不同,Quartz是多线程的;我们直接上代码!
RamJob
如果用的是上面全代码的类则把第二个方法放出来把第一个注释即可;
package com.rong.quartz01.job;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class RamJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.err.println(format.format(new Date())+" : 基于RAM的quartz调度框架定时任务...");
try {
Thread.sleep(20*1000);
System.out.println("模拟正在处理大数据....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Demo5
package com.rong.quartz01.quartz;
import com.rong.quartz01.job.RamJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.JobBuilder.newJob;
public class Demo5 {
public static void main(String[] args) throws Exception {
// 调度器创建
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
// 具体定时任务需要执行的代码
JobDetail jobDetail = newJob(RamJob.class)
.withIdentity("job2", "group1")
.withIdentity("这是一个作业类案例")
.build();
Trigger trigger = (Trigger) TriggerBuilder.newTrigger()
// 每10s执行一次
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?"))
// 触发器标识
.withIdentity("trigger2", "group1")
.withDescription("这是一个触发器")
.build();
// 调度工厂绑定作业类及触发器
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start();
}
}
main方法运行结果
这结果很明显了,看输出时间就知道相互之间不影响,并不是单线程;
两者区别总结
Spring task
优点:无需整合spring,作业类中就可以调用业务service
缺点:单线程;不能做数据存储型的定时任务
Quartz
优点:多线程;可以做数据存储型的定时任务,维护性高;
缺点:需要整合spring,不能直接调用业务层service;