Quartz—学习01—Quartz入门

Quartz入门


Quartz—学习01—Quartz入门
Quartz—学习02—Quartz源码阅读

一、Quartz的介绍

1-1、什么是Quartz

Quartz是一个由java编写的开源作业调度框架。

1-2、Quartz的基本概念

  1. Job:Job接口只用一个execute方法,Job表示每一次任务需要做的具体工作。
  2. JobDetail:用于定义作业的实例。JobDetailImpl对象中有一个jobClass对象,用于保存Job信息的。
  3. Trigger:定义执行给定作业的计划的组件。比如每天三点执行,每个月1号执行…
  4. Scheduler:与调度程序交互的主要API。Scheduler的生命周期是从其创建以后一直到调用shutdown方法为止,当你使用SchedulerFactory创建对应的Scheduler实例对象,如果没有调用shutdown方法,Scheduler将不会终止。

1-3、Quartz企业级有哪些应用

现在在一家金融机构上班,我们有应用的地方:每天、每月都会生成对账文件给到其他金融机构和银行;有些因为网络问题没有通知给商户、客户的通知,会没5分钟在把通知失败的通知在进行通知操作。

二、Quartz简单的Demo

2-1、简单实例

项目的目录结构
demo工程结构
下面是demo的pom.xml文件,引入quartz的jar包。

<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>
	<groupId>com.liu.quartz</groupId>
	<artifactId>quartz-learn-001</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>2.2.3</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

自定义Job

package com.liu.quart.job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/**
 * @desc 自定义Job,实现Quartz的Job接口,
 * 		 重写execute方法。
 */
public class CustomJob implements Job{
	
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		System.out.println("----自定义Job--的execute方法!!");
	}
}

自定义Trigger监听器

package com.liu.quart.listener;

import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.Trigger.CompletedExecutionInstruction;
import org.quartz.TriggerListener;

/**
 * @desc 自定有Trigger监听器,实现TriggerListener
 */
public class CustomTriggerListener implements TriggerListener{

	public String getName() {
		return "CustomTrigger";
	}

	public void triggerFired(Trigger trigger, JobExecutionContext context) {
		System.out.println("###################");
		System.out.println("自定义触发器----触发操作");
	}

	/**
	 * Trigger触发后,Job要执行时由Scheduler调用这个方法,如果vetoJobExecution放回是true,
	 * 则对应的Job将不会被执行。
	 */
	public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
		return false;
	}

	public void triggerMisfired(Trigger trigger) {
		System.out.println("自定义触发器----未触发操作");
	}

	/**
	 * Trigger触发后,Job被执行以后,Scheduler在调用这个方法
	 */
	public void triggerComplete(Trigger trigger, JobExecutionContext context, CompletedExecutionInstruction triggerInstructionCode) {
		System.out.println("自定义触发器----Job完成后的操作");
	}
}

测试类

package com.liu.quart;

import java.util.Date;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.SimpleTriggerImpl;
import com.liu.quart.job.CustomJob;
import com.liu.quart.listener.CustomTriggerListener;

/**
 * @desc Test类
 */
public class Test {
	public static void main(String[] args) {
		// 01-定义JobDetail
		JobDetailImpl jobDetail = new JobDetailImpl();
		jobDetail.setName("jobDetail_name");
		jobDetail.setGroup("Job_Group");
		jobDetail.setJobClass(CustomJob.class);
		
		// 02-设置触发器
		SimpleTriggerImpl trigger = new SimpleTriggerImpl();
		trigger.setName("Trigger_Name");
		trigger.setFireInstanceId("Fire_Instance");
		trigger.setStartTime(new Date());
		trigger.setRepeatCount(3);				// 重复次数
		trigger.setRepeatInterval(10000L);		// 重复间隔(ms)
		
		// 03-创建触发器,并启动
		SchedulerFactory schedulerFactory = new StdSchedulerFactory();
		Scheduler scheduler = null;
		
		try {
			scheduler = schedulerFactory.getScheduler();
			scheduler.getListenerManager().addTriggerListener(new CustomTriggerListener());
			scheduler.scheduleJob(jobDetail, trigger);
			scheduler.start();
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
}

2-2、与Spring整合的简单实例

创建一个maven的web工程,工程结构如下图
spring-quartz工程结构
pom.xml文件引入响应的文件

<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>4.3.10.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-beans</artifactId>
		<version>4.3.10.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>4.3.10.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>4.3.10.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-tx</artifactId>
		<version>4.3.10.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context-support</artifactId>
		<version>4.3.10.RELEASE</version>
	</dependency>

	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>4.3.10.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.quartz-scheduler</groupId>
		<artifactId>quartz</artifactId>
		<version>2.2.3</version>
	</dependency>
	<dependency>
		<groupId>org.quartz-scheduler</groupId>
		<artifactId>quartz-jobs</artifactId>
		<version>2.2.3</version>
	</dependency>
</dependencies>

自动以Job

/**
 * @desc 自定义Job
 */
public class CustomJob implements Job{

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		System.out.println("自定义job----执行内容");
	}
}

application.xml文件内容

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
	
	<!-- 开启注解配置 -->
	<context:annotation-config />

	<!-- 扫描包的范围 -->
	<context:component-scan base-package="com.liu"></context:component-scan>

</beans>     

spring-quartz.xml文件内容

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

	<!-- 1.JobDetail设置 -->
	<bean name="customJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
		<!-- 指定job的名称 -->
		<property name="name" value="job_name" />
		<!-- 指定job的分组 -->
		<property name="group" value="job__group" />
		<!-- 指定具体的job类 -->
		<property name="jobClass" value="com.liu.spring.quartz.job.CustomJob" />
		<!-- 必须设置为true,如果为false,当没有活动的触发器与之关联时会在调度器中会删除该任务 -->
		<property name="durability" value="true" />
		<!-- 指定spring容器的key,如果不设定在job中的jobmap中是获取不到spring容器的 -->
		<property name="applicationContextJobDataKey" value="applicationContext" />
	</bean>

	<!-- 2.触发器设置 -->
	<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<!-- 指定Trigger的名称 -->
		<property name="name" value="trigger_name" />
		<!-- 指定Trigger的名称 -->
		<property name="group" value="trigger_group" />
		<!-- 指定Tirgger绑定的Job -->
		<property name="jobDetail" ref="customJobDetail" />
		<!-- 指定Cron 的表达式 ,当前是每隔10s运行一次 -->
		<property name="cronExpression" value="0/10 * * * * ?" />
	</bean>

	<!-- 3.定义调度器,并将Trigger注册到调度器中 -->
	<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
				<ref bean="cronTrigger" />
			</list>
		</property>
	</bean>
</beans>     

web.xml内容,注意一点:不要把application.xmlspring-quartz.xml写在一起,contextConfigLocation加载的文件和springmvc加载的文件不要是一个,否则就会初始化两次,造成每次job都被运行了两次。

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
	<display-name>Archetype Created Web Application</display-name>

	<!-- 配置欢迎页面 -->
	<welcome-file-list>
		<welcome-file>/WEB-INF/context/index.jsp</welcome-file>
	</welcome-file-list>

	<!-- 最先加载的,加载其他配置文件,注意其路径问题! -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			classpath*:spring/spring-*.xml
		</param-value>
	</context-param>

	<!-- listener第二加载 -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- filter第三加载,配置编码格式的 -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!--最后加载的 -->
	<servlet>
		<servlet-name>springMVC</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring/application.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springMVC</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

三、Cron表达式

3-1、corn表达式介绍

Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式如下表,注意中文解释中用“-”是为了好看,实际域与域之间是用空格隔开的。

表达式中文解释
Seconds Minutes Hours DayofMonth Month DayofWeek Year秒-分-时-日期-月-星期-年
Seconds Minutes Hours DayofMonth Month DayofWeek秒-分-时-日期-月-星期

各个域能填的值的范围

域名取值范围可用的特殊值
秒(Seconds)0~59的整数, - * /
分(Minutes)0~59的整数, - * /
小时(Hours)0~23的整数, - * /
日期(DayofMonth)1~31的整数(但是你需要考虑你月的天数),- * ? / L W C
月份(Month)1~12的整数或者 JAN-DEC, - * /
星期(DayofWeek)1~7的整数或者 SUN-SAT (1=SUN)** , - * ? / L C #**
年(可选,留空)(Year)1970~2099, - * /

特殊符号的说明:

  • *:表示匹配该域的任意值。
  • ?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。
  • -:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次 。
  • /:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.
  • ,:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。
  • L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。
  • W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。
  • LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
  • #:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

3-2、常用corn表达式

(1)** 0 0 2 1 * ? * ** 表示在每月的1日的凌晨2点调整任务

(2)0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业

(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作

(4)0 0 10,14,16 * * ? 每天上午10点,下午2点,4点

(5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时

(6)0 0 12 ? * WED 表示每个星期三中午12点

(7)** 0 0 12 * * ? ** 每天中午12点触发

(8)**0 15 10 ? * *** 每天上午10:15触发

(9)0 15 10 * * ? 每天上午10:15触发

(10)**0 15 10 * * ? * ** 每天上午10:15触发

(11)0 15 10 * * ? 2005 2005年的每天上午10:15触发

(12)0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发

(13)0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发

(14)0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

(15)0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发

(16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发

(17)0 15 10 ? * MON-FRI 周一至周五的上午10:15触发

(18)0 15 10 15 * ? 每月15日上午10:15触发

(19)0 15 10 L * ? 每月最后一日的上午10:15触发

(20)0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发

(21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发

(22)0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发


本文参考 :
[1]: https://www.cnblogs.com/javahr/p/8318728.html

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值