更多内容,前往 IT-BLOG

一、Scheduled 定时任务


【1】添加 Scheduled相关依赖,它是 Spring自带的一个 jar包因此引入 Spring的依赖:

1 <dependency>
2 <groupId>org.springframework</groupId>
3 <artifactId>spring-context-support</artifactId>
4 </dependency>

【2】导入依赖之后,就可以在 Maven Dependencies中看到相关的依赖,如下:

【3】编写定时任务类:重点是 @Scheduled 注解和 cron 属性;

 1 /**
2 * Scheduled 定时任务
3 * 定时任务不属于持久层也不属于业务层,所以应该使用 @Component 进行标记
4 * @author Administrator
5 *
6 */
7 @Component
8 public class ScheduledDemo {
9 /**
10 * 定时任务方法,如果是定时任务方法,需要添加 scheduled注解
11 * scheduled:表示当前方法就是一个定时任务方法
12 * cron属性: 定时任务触发时间的一个字符串表达式
13 * 触发条件:每2秒触发一次,博客后面重点说 cron 表达式
14 */
15 @Scheduled(cron="0/2 * * * * ?")
16 public void scheduledMethod() {
17 System.out.println("定时任务"+new Date());
18 }
19 }

【4】在启动类中开启定时任务的启动: @EnableScheduling 注解

1 @SpringBootApplication
2 @EnableScheduling
3 public class ScheduledApplication {
4
5 public static void main(String[] args) {
6 SpringApplication.run(ScheduledApplication.class, args);
7 }
8 }

【5】cron 表达式:是一个字符串,分为 6 或 7 个域(建议使用 6个域),每个域代表一个含义 :

■  7个域:Seconds Minutes Hours Day Month Week Year (秒、分、小时、月份中的日期、月分、星期中的日期、年)
   ■  6个域(少一个 Year):Seconds Minutes Hours Day Month Week

【6】各cron 字段的含义:星期和日是有冲突的,一般会舍掉一个。表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感;

位置 时间域名 允许值 允许的特殊字符
1 0-59 , - * /
2 分钟 0-59 , - * /
3 小时 0-23 , - * /
4 0-31 , - * / ?  L W C
5 1-12 , - * /
6 星期 1-7 , - * / ? L C #
7 1970-2099 , - * /

①、星号(*):可用在所有字段中,表示对应时间域的每一个时刻。例如在秒时间域中表示每一秒;
②、问号(?):该字段只在星期和日期域中使用,它通常指定为“无意义的值”,相当于一个占位符;
③、减号(-):表示的是一个范围,如在小时字段中使用1-3,则表示 1,2,3点都执行;
④、逗号(,):表示一个列表值,如在秒域中使用 12,15表示第12秒和第15秒触发跑批;
⑤、斜杠(/):x/y 表示一个等步长序列,x为起始值,y为增量步长值,例如秒中使用 0/2 表示从0秒开始,没过2秒执行一次。
⑥、L:该字符只在日期和星期域中使用,但它在两个字段中的意思不同。L在日期字段表示月份的最后一天,如一月的31,二月的28等,如果在星期域中表示星期六(7),但是如果L出现在星期字段里,而且前面有一个数值 X,则表示这个月的最后 X 天,例如:6L表示该月的最后星期五;
⑦、W:该字符只能出现在日期域中,表示离该日期最近的工作日,例如 15W:表示离该月15号最近的工作日,如果15号是星期六则匹配星期五 14号。如果15号是星期日则匹配星期一 16日。如果15号是星期三则匹配星期三 15号本身。但需要注意关联的匹配不能够跨月,例如15号是2月的最后一天星期日,应该向下配置3月1日,但是不能跨月,只能匹配2月26星期五(2月最后一个工作日)W只能指定单一日期,不能指定范围;
⑧、LW组合:在日期字段组合使用,表示当月的最后一个工作日;
⑨、#号:该字符只能在星期域中使用,表示当月某个工作日。如6#3:表示当月的第三个星期五。
⑩、C:该字符只在日期和星期中使用,表示“Calendar” 的意思,表示计划所关联的日期。如果日期没有被关联,则表示所有日期。例如5C在日期域中表示 5日以后的第一天。1C在星期域中表示星期日后的第一天。

二、Springboot 整合Quartz 定时任务框架


Quartz 是 OpenSymphony开源组织在 Job scheduling(任务调度)领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz 可以用来创建简单或为运行十个,百个,甚至是好几万个 Jobs这样复杂的程序。Jobs 可以做成标准的 Java组件或 EJBs。Quartz是一个完全由 Java编写的开源作业调度框架。

【1】quartz 的 maven 依赖:

1 <dependency>
2 <groupId>org.quartz-scheduler</groupId>
3 <artifactId>quartz</artifactId>
4 <version>2.3.2</version>
5 </dependency>

【2】 Job(任务:你要做什么事):

 1 import org.quartz.Job;
2 import org.quartz.JobExecutionContext;
3 import org.quartz.JobExecutionException;
4
5 /**
6 * 定时任务类
7 * @author zzx
8 *
9 */
10 public class QuartzDemo implements Job{
11 /**
12 * 任务触发时所执行的方法
13 */
14 public void execute(JobExecutionContext context) throws JobExecutionException {
15 System.out.println("任务调度"+new Date());
16 }
17 }

【3】Trigger(触发器:什么时候去做):有两种形式进行表达,其中一种就是 cron 表达式

【4】scheduler(任务调度:你什么时候需要做什么事):将 job 与 Trigger 进行整合。下面是一个例子:

 1 import org.quartz.CronScheduleBuilder;
2 import org.quartz.JobBuilder;
3 import org.quartz.JobDetail;
4 import org.quartz.Scheduler;
5 import org.quartz.SimpleScheduleBuilder;
6 import org.quartz.Trigger;
7 import org.quartz.TriggerBuilder;
8 import org.quartz.impl.StdSchedulerFactory;
9
10 public class QuartzMain {
11 public static void main(String[] args) throws Exception {
12 //1、Job(任务:你要做什么事),这里使用的是建造者模式
13 JobDetail job = JobBuilder.newJob(QuartzDemo.class).build();
14 //2、Trigger(触发器:什么时候去做),这里 triggerbuilder 也是用建造者模式封装。触发条件分为两种
15 //3.1 第一种:简单的 trigger 触发时间,通过 Quartz 提供方法完成简单的重复调用。如下一个例子:每秒触发一次
16 //Trigger build = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever()).build();
17 //3.2 第二种:按照 cron 的表达式来给定触发时间
18 Trigger trigger= TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")).build();
19 //3、scheduler(任务调度:你什么时候需要做什么事) 将上面的job 和 trigger进行组装 这里使用工厂模式。
20 Scheduler defaultScheduler = StdSchedulerFactory.getDefaultScheduler();
21 defaultScheduler.scheduleJob(job, trigger);
22 //4、启动
23 defaultScheduler.start();
24 }
25 }

三、SpringBoot 整合 Quartz


【1】整合时相关依赖一下:

 1 <dependencies>
2 <dependency>
3 <groupId>org.springframework.boot</groupId>
4 <artifactId>spring-boot-starter-web</artifactId>
5 </dependency>
6
7 <dependency>
8 <groupId>org.springframework.boot</groupId>
9 <artifactId>spring-boot-starter-test</artifactId>
10 <scope>test</scope>
11 <exclusions>
12 <exclusion>
13 <groupId>org.junit.vintage</groupId>
14 <artifactId>junit-vintage-engine</artifactId>
15 </exclusion>
16 </exclusions>
17 </dependency>
18 <dependency>
19 <groupId>org.springframework</groupId>
20 <artifactId>spring-context-support</artifactId>
21 </dependency>
22
23 <!--Quartz 坐标-->
24 <dependency>
25 <groupId>org.quartz-scheduler</groupId>
26 <artifactId>quartz</artifactId>
27 <version>2.3.0</version>
28 <exclusions>
29 <exclusion>
30 <groupId>org.slf4j</groupId>
31 <artifactId>slf4j-api</artifactId>
32 </exclusion>
33 </exclusions>
34 </dependency>
35
36 <!--事务-->
37 <dependency>
38 <groupId>org.springframework</groupId>
39 <artifactId>spring-tx</artifactId>
40 </dependency>
41 </dependencies>

【2】 创建一个 Job 类:实现 Job 接口

 1 /**
2 * 定时任务类
3 * @author zzx
4 *
5 */
6 public class QuartzDemo implements Job {
7 /**
8 * 任务触发时所执行的方法
9 */
10 public void execute(JobExecutionContext context) throws JobExecutionException {
11 System.out.println("任务调度"+new Date());
12 }
13 }

【3】编写 Quartz 的配置参数

 1 import com.example.demo.scheduled.QuartzDemo;
2 import org.springframework.context.annotation.Bean;
3 import org.springframework.context.annotation.Configuration;
4 import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
5 import org.springframework.scheduling.quartz.JobDetailFactoryBean;
6 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
7 import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
8
9 /**
10 * quartz 配置类
11 */
12 @Configuration
13 public class QuartzConfig {
14 //1、创建 Job 对象
15 @Bean
16 public JobDetailFactoryBean jobDetailFactoryBean(){
17 JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
18 //通过反射的方式实例化 Job,并没有经过 spring 处理,所以依赖的对象不能通过 autowrite 注入
19 jobDetailFactoryBean.setJobClass(QuartzDemo.class);
20 return jobDetailFactoryBean;
21 }
22
23 //2、创建 Trigger 对象:也是分为两种:下面是创建一个简单的 trigger
24 //这里需要传入 JOB 对象,作为参数关联
25 /* @Bean
26 public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
27 SimpleTriggerFactoryBean simpleTriggerFactoryBean = new SimpleTriggerFactoryBean();
28 //获取 JobDetail 关联
29 simpleTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());
30 // 触发条件 该参数表示一个执行的毫秒数
31 simpleTriggerFactoryBean.setRepeatInterval(2000);
32 //设置重复次数
33 simpleTriggerFactoryBean.setRepeatCount(5);
34 return simpleTriggerFactoryBean;
35 }*/
36
37 //通过 cron 表达式表示执行 trigger
38 @Bean
39 public CronTriggerFactoryBean cronTriggerFactoryBean(){
40 CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
41 //获取 JobDetail 关联
42 cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean().getObject());
43 // 触发条件 该参数表示一个执行的毫秒数
44 cronTriggerFactoryBean.setCronExpression("0/2 * * * * ?");
45 return cronTriggerFactoryBean;
46 }
47
48 // 创建 scheduler 对象
49 @Bean
50 public SchedulerFactoryBean schedulerFactoryBean(){
51 SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
52 //关联 Trigger
53 schedulerFactoryBean.setTriggers(cronTriggerFactoryBean().getObject());
54 return schedulerFactoryBean;
55 }
56 }

【4】修改启动类

 1 /**
2 * 整合 Quartz
3 */
4 @SpringBootApplication
5 @EnableScheduling
6 public class ScheduledApplication {
7
8 public static void main(String[] args) {
9 SpringApplication.run(ScheduledApplication.class, args);
10 }
11 }

四、Job 类中注入对象


【1】给 Job 类中注入 Service 类型的对象;

 1 /**
2 * 定时任务类
3 * @author zzx
4 *
5 */
6 public class QuartzDemo implements Job {
7
8 @Autowired
9 private UserService userService;
10 /**
11 * 任务触发时所执行的方法
12 */
13 public void execute(JobExecutionContext context) throws JobExecutionException {
14 userService.test();
15 System.out.println("任务调度"+new Date());
16 }
17 }

【2】当运行时会出现空指针异常:userService 对象为空;

1 Caused by: java.lang.NullPointerException: null
2 at com.example.demo.scheduled.QuartzDemo.execute(QuartzDemo.java:25) ~[classes/:na]
3 at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.3.0.jar:na]
4 ... 1 common frames omitted

【3】没有注入 userService 的原因如下,它是通过反射创建 Job 对象,并没有经过 SpringIOC 处理,所以依赖的对象不能通过 autowrite 注入;

1 protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
2 Class<?> jobClass = bundle.getJobDetail().getJobClass();
3 return ReflectionUtils.accessibleConstructor(jobClass, new Class[0]).newInstance(new Object[0]);
4 }

【4】解决方案:重写创建 Job 的方式:并进行实例化 @Component;

 1 @Component
2 public class MyAdaptableJobFactory extends AdaptableJobFactory {
3 //将对象添加到SpringIoc容器中,并且完成该对象的属性注入
4 @Autowired
5 private AutowireCapableBeanFactory autowireCapableBeanFactory;
6
7 /**
8 * 该方法需要将实例化的 job 对象手动添加到SpringIOC 容器中并且完成实例化;
9 */
10 @Override
11 public Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
12 Object jobInstance = super.createJobInstance(bundle);
13 //将该对象加入 IOC 容器中
14 autowireCapableBeanFactory.autowireBean(jobInstance);
15 return jobInstance;
16 }
17 }

【5】 将其注入到 Quartz 的配置类中,注入到 SchedulerFactoryBean 中;

1 // 修改 SchedulerFactoryBean 类,set 创建 job 的factory 类
2 @Bean
3 public SchedulerFactoryBean schedulerFactoryBean(MyAdaptableJobFactory myAdaptableJobFactory){
4 SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
5 //关联 Trigger
6 schedulerFactoryBean.setTriggers(cronTriggerFactoryBean().getObject());
7 schedulerFactoryBean.setJobFactory(myAdaptableJobFactory);
8 return schedulerFactoryBean;
9 }

【6】测试结果:
 

【7】解决方案:在 SSM 的项目中可以通过如下方式获取依赖对象;

1 //根据spring的配置文件得到ioc容器对象
2 ApplicationContext context =
3 new ClassPathXmlApplicationContext("spring.xml");
4 Person person = context.getBean(Person.class);
 

SpringBoot 整合Quartz 定时任务框架的更多相关文章

  1. SpringBoot整合Quartz定时任务 系统job Spring Boot教程 调度任务

    原文地址:https://www.cnblogs.com/allalongx/p/8477368.html 构建工程 创建一个Springboot工程,在它的程序入口加上@EnableScheduli ...

  2. SpringBoot整合Quartz定时任务

    记录一个SpringBoot 整合 Quartz 的Demo实例 POM.XML文件 <!-- 定时器任务 quartz需要导入的坐标 --> <dependency> < ...

  3. SpringBoot整合Quartz定时任务(持久化到数据库)

    背景 最近在做项目,项目中有个需求:需要使用定时任务,这个定时任务需要即时生效.查看Quartz官网之后发现:Quartz提供两种基本作业存储类型: RAMJobStore :RAM也就是内存,默认情 ...

  4. SpringBoot整合Quartz定时任务 的简单实例 2

    (1)什么是Quartz?(2)Quartz的特点:(3)Quartz专用词汇说明:(4)Quartz任务调度基本实现原理: 接下来看下具体的内容: (1)什么是Quartz? Quartz是一个完全 ...

  5. SpringBoot整合Quartz定时任务 的简单实例

    POM.XML文件 <!-- 定时器任务 quartz需要导入的坐标 --> <dependency> <groupId>org.quartz-scheduler& ...

  6. Spring整合Quartz定时任务 在集群、分布式系统中的应用(Mysql数据库环境)

    Spring整合Quartz定时任务 在集群.分布式系统中的应用(Mysql数据库环境)   转载:http://www.cnblogs.com/jiafuwei/p/6145280.html 单个Q ...

  7. SpringBoot整合Quartz及log4j实例

    SpringBoot整合Quartz及log4j实例 因为之前项目中经常会做一些定时Job的东西,所以在此记录一下,目前项目中已经使用elastic-job,这个能相对比Quartz更加简单方便一些, ...

  8. Spring整合Quartz定时任务执行2次,Spring定时任务执行2次

    Spring整合Quartz定时任务执行2次,Spring定时任务执行2次 >>>>>>>>>>>>>>>&g ...

  9. SpringBoot之整合Quartz调度框架-基于Spring Boot2.0.2版本

    1.项目基础 项目是基于Spring Boot2.x版本的 2.添加依赖 <!-- quartz依赖 --> <dependency> <groupId>org.s ...

  10. SpringBoot整合Quartz作为调度中心完整实用例子

    因为想要做一个类似于调度中心的东西,定时执行一些Job(通常是一些自定义程序或者可执行的jar包),搭了一个例子,总结了前辈们的相关经验和自己的一些理解,如有雷同或不当之处,望各位大佬见谅和帮忙指正. ...

随机推荐

  1. 【BOOK】正则表达式

    正则表达式 1. 开源中国-正则表达式测试工具:https://tool.oschina.net/regex/ 2. 匹配规则 3. match() 从字符串起始位置匹配正则表达式 若从起始位置匹配不 ...

  2. 通过ref调取子组件方法

    子 async update(res){ //this.$refs.child.animates(); this.userform = res; }, 主 <DetailEdit @detail ...

  3. adaptsegnet 论文分析比较好的

    https://blog.csdn.net/weixin_43795588/article/details/118058775 常用的语义分割一般是由两部分组成:一部分是特征提取器,比如可以用Resn ...

  4. 一个线程池的c++实现

    前面我们实现了CallBack类,实现了对任意可调用对象的封装,且统一了调用接口. 现在利用CallBack类,我们来实现一个线程池,我们的线程池包含: 1. 状态机, 用于控制和管理线程池的运行.停 ...

  5. std::unique_ptr release的使用

    在c++中,动态内存管理是通过new/delete 运算符来进行的.由于确保在正确的时间释放内存是很困难的,为了避免内存泄漏,更加容易,安全地使用动态内存,C++11标准库提供了两种智能指针类型来管理 ...

  6. idea 部署项目到 docker 运行

    1.在远程服务器上开启 docker 远程连接 $vim /usr/lib/systemd/system/docker.service # ExecStart=/usr/bin/dockerd -H ...

  7. C#——》发布ASP.NET Core项目到Windows IIS服务器中环境部署

    服务器:Windows Server2012 R2 IIS:8 .net Core版本:1.1.2 一,在VS中点击项目-->依赖项-->SDK下可以查看当前项目.Net core是哪个版 ...

  8. Jmeter、Postman之RSA加密登录接口测试

    方法1:直接用在线加密工具进行加密,得到密码 参考地址 https://www.toolscat.com/decode/rsa 输入公钥和密码,直接加密即可   方法2:postman工具 步骤1:接 ...

  9. Flink状态后端的对比及机制

    1. Flink状态后端的类型: MemoryStateBackend FsStateBackend RocksDBStateBackend 2. 各状态后端对比: 2.1 MemoryStateBa ...

  10. 配置Nginx 反向代理 + go在windows 环境下编译运行在linux的文件

    在源码根目录下 创建build.bat: set GOOS=linux set GOARCH=amd64 go build -o build/myweb main.go 在终端执行: ./build. ...