quartz详解

article/2025/8/22 13:35:25

quartz

一、Quartz相关介绍
1.简介
 1.1 Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。
 1.2 Quartz 可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。
 1.3 Quartz 允许程序开发人员根据时间的间隔来调度作业。
 1.4 Quartz 实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。

2.Quartz 核心概念
  我们需要明白 Quartz 的几个核心概念,这样理解起 Quartz 的原理就会变得简单了。
 2.1 Job 表示一个工作,要执行的具体内容。此接口中只有一个方法,如下:

void execute(JobExecutionContext context)

2.2 JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
 2.3 Trigger 代表一个调度参数的配置,什么时候去调。
 2.4 Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

项目层级
在这里插入图片描述

先说说常见的几种定时方法

线程休眠

先讲个故事

一名程序员网友发帖晒出了自己写的一段代码,是一段定时代码,根据他的语气,可以看出他对自己写的代码感觉很好,是一段java代码,好家伙,代码中多线程都用上了,还有sleep,然后自己这样写了就直接被老板赶走了,走之前为了面子还说到,你这公司我还看不上呢,其实一想写的确实没问题功能能实现,但是

Java线程实现采用内核线程实现,线程的休眠及唤醒(状态切换)需借助操作系统进行,这是一个极其耗时耗力的操作。在线程休眠或运行时间较长的情景下,其对性能的影响还不算明显,因为对线程状态的切换并不频繁。但若线程休眠及运行的时间都很短(例如毫秒/秒,文中案例就是一个典型案例),系统将频繁的对线程状态进行切换,导致严重的性能损耗,并对着循环次数的递增而放大。

所以是不推荐使用的!

/**** 使用线程休眠实现定时任务,这种写法是不建议写的*/
public class Task01 {public static void main(String[] args) {Thread myThread = new Thread(new Runnable() {@Overridepublic void run() {while (true) {System.out.println("TestThreadWait is called!");try {// 使用线程休眠来实现周期执行Thread.sleep(1000 * 3);} catch (InterruptedException e) {e.printStackTrace();}}}});myThread.start();}
}

Timer

/**** 延时任务*/
public class Task02 {public static void main(String[] args) {Timer timer = new Timer();/**** 参数一:需要执行的任务* 参数二:延迟多久   参数二不加只会执行一次=定时任务* 参数三,执行的频率*/timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("使用timer实现定时任务");}}, 0,1000);}
}

通过ScheduledExecutorService实现定时任务

package com.changan.test;import com.sun.org.apache.bcel.internal.generic.NEW;import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/*** @program: springcloudalibaba* @description:* @author: Mr.shen* @create: 2022-06-27 09:35**/
public class Task03 {public static void main(String[] args) {Runnable runnable= new Runnable() {@Overridepublic void run() {System.out.println("通过ScheduledExecutorService实现定时任务");}};ScheduledExecutorService service= Executors.newSingleThreadScheduledExecutor();service.scheduleAtFixedRate(runnable,1,2, TimeUnit.SECONDS);}
}

进阶

quartz(编写触发器和调度器 )

package com.changan.test;/*** @program: springcloudalibaba* @description: 编写触发器和调度器* @author: Mr.shen* @create: 2022-06-27 10:28**/
import com.changan.job.HelloJob;
//import com.changan.test.service.HelloJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;public class HelloSchedulerDemo {public static void main(String[] args) throws Exception{//1、调度器(Schedular),从工厂中获取调度实例(默认:实例化new StdSchedulerFactory();)Scheduler scheduler= StdSchedulerFactory.getDefaultScheduler();//2、任务实例(JobDetail)JobDetail jobDetail= JobBuilder.newJob(HelloJob.class) //加载任务类,与HelloJob完成绑定,要求HelloJob实现Job接口.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();}
}

job

package com.changan.job;/*** @program: springcloudalibaba* @description: 编写一个Job类,用来编写定时任务要做什么* @author: Mr.shen* @create: 2022-06-27 10:25**/
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;import java.text.SimpleDateFormat;
import java.util.Date;public class HelloJob implements Job {public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {//输出当前时间Date date=new Date();SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateString=dateFormat.format(date);//工作内容System.out.println("执行定时任务,时间是:"+dateString);}
}

高阶(使用springboot整合quartz并插入一条数据进入数据库)

下面也需要用到CronExpression表达式

推荐一个博主写的博客写的很好yyds

https://blog.csdn.net/ca1993422/article/details/123723693?spm=1001.2014.3001.5501

yaml

server:port: 8085
spring:application:name: quartz-servicedatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/tcw?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNullusername: rootpassword: 123456mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl   #??????map-underscore-to-camel-case: true    #??????? ????????create_time?????_??mapper-locations: classpath*:/mapper/*Mapper.xml  #????type-aliases-package: com.changan.entity  #??

pom.xml

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency><!-- mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies>

启动器

package com.changan;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;/*** @program: springcloudalibaba* @description: 启动类* @author: Mr.shen* @create: 2022-06-27 09:42**//**** @EnableScheduling:开启定时任务*/
@MapperScan("com.changan.mapper")
@SpringBootApplication
@EnableScheduling
public class QuarzApplication {public static void main(String[] args) {SpringApplication.run(QuarzApplication.class,args);}}

Quartz配置类

package com.changan.config;import com.changan.adapter.MyadaptableJobFactory;
import com.changan.job.QuartzDemo;
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;/*** @program: springcloudalibaba* @description: Quartz配置类* @author: Mr.shen* @create: 2022-06-27 10:54**/
@Configuration
public class QuartzConfig {/*** 1、创建Job对象*/@Beanpublic JobDetailFactoryBean jobDetailFactoryBean(){JobDetailFactoryBean factoryBean=new JobDetailFactoryBean();//关联我们自己的Job类factoryBean.setJobClass(QuartzDemo.class); //就是触发这个定时任务执行的任务return factoryBean;}/*** 2、创建Trigger对象*/@Beanpublic CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){CronTriggerFactoryBean factoryBean=new CronTriggerFactoryBean();factoryBean.setJobDetail(jobDetailFactoryBean.getObject());//将任务代进去factoryBean.setCronExpression("0/5 * * * * ?");//设置任务触发条件 CronExpression表达式return factoryBean;}/*** 3、创建Scheduler* 实现调度任务的配置*/@Beanpublic SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean, MyadaptableJobFactory myadaptableJobFactory){SchedulerFactoryBean  factoryBean=new SchedulerFactoryBean();factoryBean.setTriggers(cronTriggerFactoryBean.getObject());factoryBean.setJobFactory(myadaptableJobFactory);return factoryBean;}
}

Job类(就是你时间到了触发的方法)

	package com.changan.job;import com.changan.entity.User;
import com.changan.service.Userservice;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;import java.util.Date;/*** @program: springcloudalibaba* @description: job类* @author: Mr.shen* @create: 2022-06-27 10:40**/
public class QuartzDemo implements Job {@Autowiredprivate Userservice userService;@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {User user = new User();user.setAge(12);user.setHead("dwwd");user.setManager(123);user.setSex("dw");user.setUpwd("wdwdw");user.setUname("111");System.out.println(userService.userinsert(user));System.out.println("Execute..."+new Date());}
}

做完这些操作之后你运行插入你会发现Userservice并没有注入bean 就算加service也不行下面就需要一个配置类了

MyadaptableJobFactory(注入对象)

package com.changan.adapter;/*** @program: springcloudalibaba* @description: 编写一个类MyAdaptableJobFactory继承AdaptableJobFactory,覆盖createJobInstance()方法。* @author: Mr.shen* @create: 2022-06-27 10:54**/
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可以将一个对象添加到Spring IOC容器中,并且完成该对象注入@Autowiredprivate AutowireCapableBeanFactory autowireCapableBeanFactory;//该方法将实例化的任务对象手动的添加到SpringIOC容器中并且完成对象的注入@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {Object object = super.createJobInstance(bundle);//将object对象添加到Spring IOC容器中并完成注入this.autowireCapableBeanFactory.autowireBean(object);return object;}
}

http://chatgpt.dhexx.cn/article/vynObZVy.shtml

相关文章

【开发经验】quartz表结构说明(字段说明)

文章目录 一、quartz表信息二、表字段说明1.qrtz_blob_triggers2.qrtz_calendars3.qrtz_cron_triggers4.qrtz_fired_triggers5.qrtz_job_details6. qrtz_locks7.qrtz_paused_trigger_grps8. qrtz_scheduler_state9.qrtz_simple_triggers10.qrtz_triggers 一、quartz表信息 qrt…

Quartz简介

文章目录 Quartz 是什么What is the Quartz Job Scheduling Library?使用场景特点Quartz 使用的设计模式 Java 语言实现定时任务的几种方式核心元素SchedulerTriggerCalendarJobDetailJobJobExecutionContext 核心元素之间的关系Quartz 类图主要线程数据存储 最近做了一个活动…

【quartz表结构及说明】

文章目录 一、quartz表信息二、表字段说明 1.qrtz_blob_triggers2.qrtz_calendars3.qrtz_cron_triggers4.qrtz_fired_triggers5.qrtz_job_details6. qrtz_locks7.qrtz_paused_trigger_grps8. qrtz_scheduler_state9.qrtz_simple_triggers10.qrtz_triggers 一、quartz表信息 qr…

Quartz数据库表分析

2019独角兽企业重金招聘Python工程师标准>>> 系列文章 Spring整合Quartz分布式调度 Quartz数据库表分析 Quartz调度源码分析 前言 上一篇文章Spring整合Quartz分布式调度介绍了Quartz通过数据库的方式来实现分布式调度&#xff0c;通过使用数据库来存储trigger&…

php rsa公钥加密,PHP RSA加密

这两天正好做一个rsa加密,现在就总结一下其中的几个要点。 1.什么是rsa算法 RSA公钥加密算法是1977年由罗纳德李维斯特(Ron Rivest)、阿迪萨莫尔(Adi Shamir)和伦纳德阿德曼(Leonard Adleman)一起提出的。1987年7月首次在美国公布,当时他们三人都在麻省理工学院工作实习。RSA…

php 代码加密运行,php加密后可以直接运行吗

加密后的php代码需要ZendGuardLoader模块才能正常运行 下载ZendGuardLoader压缩包 下载好后解压压缩包&#xff0c;找到目录下的 ZendLoader.dll 文件&#xff0c;将它放到你的php目录下ext下&#xff0c;再编辑php.ini文件&#xff0c;添加一段代码&#xff1a;[Zend.loader] …

PHP加密 php源代码在线加密工具推荐

在我们开发的项目中&#xff0c;有一部分可能是用于商业用途&#xff0c;会部署在客户提供的机器环境中。因为 PHP 本身是解释型语言&#xff0c;所以未进行处理的代码&#xff0c;就会有泄露或被修改的风险。那么我们可能会想到最简单有效的方法就是进行PHP代码的加密&#xf…

PHP数据加密的几种方式

首先我们来了解一下为什么要加密&#xff1f; 在网络通信的过程中攻击者可以伪造请求和返回&#xff0c;从而达到不可告人的目的。如下图所示&#xff1a; 数据加密之后可以防止他人监听窃取信息以及通讯内容被篡改。 了解了加密的作用&#xff0c;我再来说说加密的方式&…

php代码加密 php-screw-plus

1.下载本程序并解压到某个目录 下载 https://gitee.com/splot/php-screw-plus 2.解压 3.编译 进入目录 /usr/local/php/bin/phpize &#xff08;在screw plus目录中执行php bin中的phpize自动生成扩展所需文件&#xff09; ./configure --with-php-config/usr/local/php…

php代码加密

如何对PHP文件进行加密——ZendGuard加密与ZendLoader解密 end Guard是目前市面上最成熟的PHP源码加密产品。 经过本人搜集资料&#xff0c;亲身测试后&#xff0c;总结了如何利用Zend Guard对PHP文件进行加密&#xff0c;以及如何利用Zend Loader对加密后的PHP文件进行解密。 …

php7 加密扩展,一个PHP7 代码的加密扩展,

一个PHP7 代码的加密扩展是PHP7代码的加密扩展&#xff0c; PHP7栏目介绍如何加密扩展 推荐&#xff1a;PHP7 介绍 一个简洁高效的跨 特点 简单快速&#xff0c;实际测量后几乎不影响性能。它与其他扩展兼容&#xff0c;如OPcache和Xdebug。它支持Linux、macOS、Windows等系统。…

PHP源代码加密后正常运行

因为老板想对做出来的产品进行加密防止进行修改&#xff0c;和源代码的流逝&#xff0c;让我们看看有没有加密的方法。所以通过网上找到了相关的一些教程&#xff0c;还可以&#xff0c;记录一下 在这使用的是 php screw plus github地址 https://github.com/del-xiong/screw-p…

看我如何玩转PHP代码加密与解密

参考文献&#xff1a; https://xz.aliyun.com/t/2403 前言 两次比赛&#xff0c;两个题目&#xff0c;两种方式&#xff0c;两个程序。 一切PHP的代码终究是要到Zend Engine上走一走的&#xff0c;因此一切PHP的源码加密都是可以被解密的。&#xff08;不包括OpCode混淆-VM…

一文打尽PHP代码加密方式

原文地址 温馨提示&#xff1a;世界上没有破不了的密码&#xff0c;如果有那也只是时间问题。 我们能做的只是增加破解时间。如果这个破解时间大于一个人的寿命&#xff0c;那么这个加密方式肯定是成功的。 对于加密的程序&#xff0c;就像破解者需要了解、猜测编写者的思路…

大数据运维工程师面试

当前你们公司使用的Hadoop版本是什么 ambari2.5.1 Hadoop 2.7.3.2.6.2.14-5HDFS常见的数据压缩格式有哪些&#xff0c;介绍其中一种详细的实现方式 1 gzip压缩 优点&#xff1a;压缩率比较高&#xff0c;而且压缩/解压速度也比较快&#xff1b;hadoop本身支持&#xff0c;在…

Linux运维工程师常见基础面试题

1、tcp三次握手四次挥手详解 TCP是一种面向连接的协议&#xff0c;通信前需要建立连接&#xff0c;通信结束后需要释放连接。TCP通过三次握手建立连接&#xff0c;四次挥手释放连接。 三次握手&#xff1a; 1、客户端向服务器发送SYN包&#xff0c;表示请求建立连接。 2、服务…

运维工程师面试总结(含答案)

运维工程师面试总结 原文链接&#xff1a;https://www.cuiliangblog.cn/detail/article/2 一、linux 1. linux系统启动流程 第一步&#xff1a;开机自检&#xff0c;加载BIOS第二步&#xff1a;读取&#xff2d;&#xff22;&#xff32;第三步&#xff1a;Boot Loader grub…

Linux运维工程师面试题(1)

文章目录 Linux运维工程师面试题&#xff08;1&#xff09;1 别名、内部命令、外部命令的执行顺序2 linux 系统启动流程3 破解用户密码的方法4 忘记 grub 密码怎么解决5 硬盘空间满了怎么处理&#xff0c;怎么找到硬盘中的大文件6 硬盘明明有很多空间&#xff0c;为什么无法存储…

Linux运维工程师面试题整理

1.Nginx反向代理&#xff0c;负载均衡&#xff0c;动静分离&#xff0c;工作原理及优化 nginx配置反向代理。 vim Nginx.conf Server模块中配置 Listen 80 Server_name ip; 在server段里面的location加上proxy_pass http://ip:端口; Nginx配置完成后重启一下nginx。 配…

FastReport打印标签

1、选择标签向导 2、在这里可以选择自己想要的标签布局&#xff0c;也可以点击左下角的自定义标签 3、点击自定义标签后&#xff0c;可以自定义自己想要的标签 4、点击确定之后&#xff0c;可以在制造商找到自定义&#xff0c;选择自定义的标签1 5、然后可以在数据区自定义想要…