Quartz
- 1.整合
- 1.1 mysql中创建quartz表
- 1.2 添加quartz依赖
- 1.3 添加quartz.properties与数据库关联
- 1.4 编写quartzConfig文件
- 1.4.1 quartz的初始化配置
- 1.4.2 创建job 实例工厂
- 1.5 编写定时任务
- 1.5.1 静态方式编写定时任务
- 1.5.2 动态方式编写定时任务
- 2.quartz
- 2.1 quartz概念
- 2.2 quartz核心要素
- 2.2.1 要素关系
- 2.2.2 要素作用
- 2.3 quartz优点
- 2.4 quartz数据表
- 2.4.1 数据表获取路径
- 2.4.1 数据表的作用
- 2.5 cron表达式
- 3.参考文章
整合步骤:
1.在数据库中添加quartz的表
2.pom.xml文件中添加依赖
3.添加quartz.properties的配置
4.编写quartzConfig文件
5.编写定时任务
1.整合
1.1 mysql中创建quartz表
#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;CREATE TABLE QRTZ_JOB_DETAILS(SCHED_NAME VARCHAR(120) NOT NULL,JOB_NAME VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,DESCRIPTION VARCHAR(250) NULL,JOB_CLASS_NAME VARCHAR(250) NOT NULL,IS_DURABLE VARCHAR(1) NOT NULL,IS_NONCONCURRENT VARCHAR(1) NOT NULL,IS_UPDATE_DATA VARCHAR(1) NOT NULL,REQUESTS_RECOVERY VARCHAR(1) NOT NULL,JOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);CREATE TABLE QRTZ_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,JOB_NAME VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,DESCRIPTION VARCHAR(250) NULL,NEXT_FIRE_TIME BIGINT(13) NULL,PREV_FIRE_TIME BIGINT(13) NULL,PRIORITY INTEGER NULL,TRIGGER_STATE VARCHAR(16) NOT NULL,TRIGGER_TYPE VARCHAR(8) NOT NULL,START_TIME BIGINT(13) NOT NULL,END_TIME BIGINT(13) NULL,CALENDAR_NAME VARCHAR(200) NULL,MISFIRE_INSTR SMALLINT(2) NULL,JOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);CREATE TABLE QRTZ_SIMPLE_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,REPEAT_COUNT BIGINT(7) NOT NULL,REPEAT_INTERVAL BIGINT(12) NOT NULL,TIMES_TRIGGERED BIGINT(10) NOT NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_CRON_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,CRON_EXPRESSION VARCHAR(200) NOT NULL,TIME_ZONE_ID VARCHAR(80),PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_SIMPROP_TRIGGERS( SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,STR_PROP_1 VARCHAR(512) NULL,STR_PROP_2 VARCHAR(512) NULL,STR_PROP_3 VARCHAR(512) NULL,INT_PROP_1 INT NULL,INT_PROP_2 INT NULL,LONG_PROP_1 BIGINT NULL,LONG_PROP_2 BIGINT NULL,DEC_PROP_1 NUMERIC(13,4) NULL,DEC_PROP_2 NUMERIC(13,4) NULL,BOOL_PROP_1 VARCHAR(1) NULL,BOOL_PROP_2 VARCHAR(1) NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_BLOB_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,BLOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_CALENDARS(SCHED_NAME VARCHAR(120) NOT NULL,CALENDAR_NAME VARCHAR(200) NOT NULL,CALENDAR BLOB NOT NULL,PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL, PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);CREATE TABLE QRTZ_FIRED_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,ENTRY_ID VARCHAR(95) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,INSTANCE_NAME VARCHAR(200) NOT NULL,FIRED_TIME BIGINT(13) NOT NULL,SCHED_TIME BIGINT(13) NOT NULL,PRIORITY INTEGER NOT NULL,STATE VARCHAR(16) NOT NULL,JOB_NAME VARCHAR(200) NULL,JOB_GROUP VARCHAR(200) NULL,IS_NONCONCURRENT VARCHAR(1) NULL,REQUESTS_RECOVERY VARCHAR(1) NULL,PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);CREATE TABLE QRTZ_SCHEDULER_STATE(SCHED_NAME VARCHAR(120) NOT NULL,INSTANCE_NAME VARCHAR(200) NOT NULL,LAST_CHECKIN_TIME BIGINT(13) NOT NULL,CHECKIN_INTERVAL BIGINT(13) NOT NULL,PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);CREATE TABLE QRTZ_LOCKS(SCHED_NAME VARCHAR(120) NOT NULL,LOCK_NAME VARCHAR(40) NOT NULL, PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);commit;
1.2 添加quartz依赖
<!--quartz--><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.3</version><exclusions><exclusion><artifactId>slf4j-api</artifactId><groupId>org.slf4j</groupId></exclusion></exclusions></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>2.2.3</version><exclusions><exclusion><artifactId>slf4j-api</artifactId><groupId>org.slf4j</groupId></exclusion></exclusions></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency>
1.3 添加quartz.properties与数据库关联
org.quartz.scheduler.instanceName=quartzScheduler
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.rmi.export=false
org.quartz.scheduler.rmi.proxy=false
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
org.quartz.jobStore.misfireThreshold=50000
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.useProperties=false
org.quartz.jobStore.clusterCheckinInterval=20000
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=10
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
数据库关联
package com.foxconn.fii.taskz.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;import javax.sql.DataSource;/*** @author*/
@Configuration
@PropertySource("classpath:application.properties")
public class DataSourceQuartzConfig {@Value("${spring.datasource.url}")private String url;@Value("${spring.datasource.username}")private String user;@Value("${spring.datasource.password}")private String password;@Value("${spring.datasource.driverClassName}")private String driverClass;@Value("${spring.datasource.druid.maxActive}")private Integer maxActive;@Value("${spring.datasource.druid.minIdle}")private Integer minIdle;@Value("${spring.datasource.druid.initialSize}")private Integer initialSize;@Value("${spring.datasource.druid.maxWait}")private Long maxWait;@Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")private Long timeBetweenEvictionRunsMillis;@Value("${spring.datasource.druid.minEvictableIdleTimeMillis}")private Long minEvictableIdleTimeMillis;@Value("${spring.datasource.druid.testWhileIdle}")private Boolean testWhileIdle;@Value("${spring.datasource.druid.testWhileIdle}")private Boolean testOnBorrow;@Value("${spring.datasource.druid.testOnBorrow}")private Boolean testOnReturn;@Bean(name = "quartzDataSource")public DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driverClass);dataSource.setUrl(url);dataSource.setUsername(user);dataSource.setPassword(password);//连接池配置dataSource.setMaxActive(maxActive);dataSource.setMinIdle(minIdle);dataSource.setInitialSize(initialSize);dataSource.setMaxWait(maxWait);dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);dataSource.setTestWhileIdle(testWhileIdle);dataSource.setTestOnBorrow(testOnBorrow);dataSource.setTestOnReturn(testOnReturn);dataSource.setValidationQuery("SELECT 'x'");dataSource.setPoolPreparedStatements(true);dataSource.setMaxPoolPreparedStatementPerConnectionSize(20);return dataSource;}
}
1.4 编写quartzConfig文件
1.4.1 quartz的初始化配置
package com.fii.gac.web.config;import java.io.IOException;
import java.util.Properties;import javax.sql.DataSource;import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;/*** quartz的初始化配置* @author Administrator**/
@Configuration
@RequiredArgsConstructor
public class QuartzConfiguration {private final QuartzJobFactory quartzJobFactory;private final DataSource dataSource;@Bean(name = "schedulerFactoryBean")public SchedulerFactoryBean schedulerFactoryBean() throws IOException {//获取配置属性PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));//在quartz.properties中的属性被读取并注入后再初始化对象propertiesFactoryBean.afterPropertiesSet();//创建SchedulerFactoryBeanSchedulerFactoryBean factory = new SchedulerFactoryBean();Properties pro = propertiesFactoryBean.getObject();//覆盖已存在的任务factory.setOverwriteExistingJobs(true);// 设置自动启动factory.setAutoStartup(true);// 设置延迟10s启动factory.setStartupDelay(10);if (pro != null) {factory.setQuartzProperties(pro);}factory.setJobFactory(quartzJobFactory);factory.setDataSource(dataSource);return factory;}
}
1.4.2 创建job 实例工厂
package com.fii.gac.web.config;import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.springframework.stereotype.Component;/*** 创建job 实例工厂,解决spring注入问题,如果使用默认会导致spring的@Autowired 无法注入问题(很重要)* @author Administrator**/
@Component
public class QuartzJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {private transient AutowireCapableBeanFactory beanFactory;@Overridepublic void setApplicationContext(final ApplicationContext context) {beanFactory = context.getAutowireCapableBeanFactory();}@Overrideprotected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {final Object job = super.createJobInstance(bundle);beanFactory.autowireBean(job);return job;}}
1.5 编写定时任务
1.5.1 静态方式编写定时任务
/*** 静态方式配置定时任务** @param jobDetail* @return*/@Beanpublic CronTriggerFactoryBean simpleJobTrigger(@Qualifier("simpleJobDetail") JobDetail jobDetail) {CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();factoryBean.setJobDetail(jobDetail);factoryBean.setStartDelay(1000L);factoryBean.setName("trigger2");factoryBean.setGroup("group1");//周1至周5,每天上午8点至下午18点,每分钟执行一次factoryBean.setCronExpression("0 0/1 8-18 ? * 2-6");return factoryBean;}@Beanpublic JobDetailFactoryBean simpleJobDetail() {JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();factoryBean.setJobClass(ScheduledJob.class);factoryBean.setGroup("group1");factoryBean.setName("job4");return factoryBean;}
执行结果:

1.5.2 动态方式编写定时任务
代码不全,只是为了展示编写方法
public void execute(JobExecutionContext context) throws JobExecutionException {preExecute(context);try {executeWrapper(context);setStatus(1);} catch (Exception e) {setStatus(0);String exceptionString = Exceptions.getStackTrace(e);addDescription(exceptionString);log.error(exceptionString);}postExecute(context);clearAll();}protected void preExecute(JobExecutionContext context) {initThreadLocal();try {LocalDateTime now = LocalDateTime.now();JobKey jobKey = context.getJobDetail().getKey();JobDataMap jobDataMap = context.getMergedJobDataMap();String jobName = jobKey.getName();String jobGroup = jobKey.getGroup();// 更状态QuartzJobDetailPO jobDetailPO = quartzJobDetailMapper.findByGroupAndName(jobGroup, jobName);jobDetailPO.setStatus(1);quartzJobDetailMapper.updateById(jobDetailPO);jobDataMap.put("startTime", now);log.info("jobGroup: {}, jobName: {}, startTime: {}", jobGroup, jobName, DateTimes.dateTimeToString(now));} catch (Exception e) {log.error(Exceptions.getStackTrace(e));}}protected void postExecute(JobExecutionContext context) {try {LocalDateTime now = LocalDateTime.now();JobKey jobKey = context.getJobDetail().getKey();JobDataMap jobDataMap = context.getMergedJobDataMap();String jobName = jobKey.getName();String jobGroup = jobKey.getGroup();LocalDateTime startTime = (LocalDateTime) jobDataMap.get("startTime");int executeTime = (int) startTime.until(now, ChronoUnit.SECONDS);LoadDataJobResult result = LOAD_DATA_JOB_RESULT_THREAD_LOCAL.get();// 更新状态QuartzJobDetailPO jobDetailPO = quartzJobDetailMapper.findByGroupAndName(jobGroup, jobName);jobDetailPO.setLastRunResult(result.getStatus());jobDetailPO.setLastRunTime(startTime);jobDetailPO.setNextRunTime(Quartzs.getCronNextRunTime(jobDetailPO.getCronExpression()));jobDetailPO.setStatus(2);quartzJobDetailMapper.updateById(jobDetailPO);quartzJobLogMapper.insert(QuartzJobLogPO.builder().jobGroup(jobGroup).jobName(jobName).status(result.getStatus()).description(result.getStatus() == 1 ? Jsons.objectToJson(result) : result.getDescription()).executeTime(executeTime).addTime(now).build());log.info("jobGroup: {}, jobName: {}, endTime: {}, 耗时: {}", jobGroup, jobName,DateTimes.dateTimeToString(now),executeTime);}catch (Exception e) {log.error(Exceptions.getStackTrace(e));}}
2.quartz
2.1 quartz概念
Quartz是一个开源的任务调度框架。基于定时、定期的策略来执行任务是它的核心功能,可以用来创建简单或运行十个,百个,甚至是好几万个Jobs这样复杂的程序。quartz官网
2.2 quartz核心要素
Quartz有3个核心要素:调度器(Scheduler)、任务(Job)、触发器(Trigger)。
2.2.1 要素关系

2.2.2 要素作用
Job(任务):是一个接口,有一个方法void execute(),可以通过实现该接口来定义需要执行的任务(具体的逻辑代码)。Trigger(触发器):描述触发Job执行的时间触发规则实现类SimpleTrigger和CronTrigger可以通过crom表达式定义出各种复杂的调度方案。Scheduler(调度器):代表一个Quartz的独立运行容器。Trigger和JobDetail可以注册到Scheduler中。Scheduler可以将Trigger绑定到某一JobDetail上,这样当Trigger被触发时,对应的Job就会执行。一个Job可以对应多个Trigger,但一个Trigger只能对应一个Job.
补充说明
JobDetail:Quartz每次执行job时,都重新创建一个Job实例,会接收一个Job实现类,以便运行的时候通过newInstance()的反射调用机制去实例化Job.JobDetail是用来描述Job实现类以及相关静态信息,比如任务在scheduler中的组名等信息。Calendar:是一些日历特定时间的集合。一个Trigger可以和多个 calendar关联,比如每周一早上10:00执行任务,法定假日不执行,则可以通过calendar进行定点排除。
2.3 quartz优点
Quartz提供了极为广泛的特性如持久化任务,集群和分布式任务等,其特点如下:
完全由Java写成,方便集成(Spring)
伸缩性
负载均衡
高可用性
2.4 quartz数据表
2.4.1 数据表获取路径
quartz数据表的获取路径: 官网—>官网下载quartz---->quartz-2.2.3-distribution.tar\quartz-2.2.3\docs\dbTables
多种数据表文件

2.4.1 数据表的作用
QRTZ_CALENDARS 以 Blob 类型存储 Quartz 的 Calendar 信息 QRTZ_CRON_TRIGGERS 存储 Cron Trigger,包括 Cron表达式和时区信息 QRTZ_FIRED_TRIGGERS 存储与已触发的 Trigger 相关的状态信息,以及相联 Job的执行信息 QRTZ_PAUSED_TRIGGER_GRPS 存储已暂停的 Trigger 组的信息 QRTZ_SCHEDULER_STATE 存储少许的有关 Scheduler 的状态信息,和别的 Scheduler实例(假如是用于一个集群中) 对象QRTZ_LOCKS 存储程序的悲观锁的信息(假如使用了悲观锁) QRTZ_JOB_DETAILS 存储每个已配置的 Job 的详细信息 QRTZ_JOB_LISTENERS 存储有关已配置的 JobListener 的信息 QRTZ_SIMPLE_TRIGGERS 存储简单的Trigger,包括重复次数,间隔,以及已触的次数 QRTZ_BLOG_TRIGGERS Trigger 做为 Blob 类型存储(用于 Quartz 用户用 JDBC建立他们本身定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候) 集群QRTZ_TRIGGER_LISTENERS 存储已配置的 TriggerListener 的信息 配置QRTZ_TRIGGERS 存储已配置的 Trigger 的信息
2.5 cron表达式
cron表达式支持到七个,其中参数如下:

字符表达的意思
1)* 星号
使用星号(*) 指示着你想在这个域上包含所有合法的值,在你希望 trigger 在该域的所有有效值上被激发时使用 * 字符。例如,在月份域上使用星号意味着每个月都会触发这个 trigger。表达式样例:0 * 17 * * ?
意义:每天从下午5点到下午5:59中的每分钟激发一次 trigger。它停在下午 5:59 是因为值 17 在小时域上,在下午 6 点时,小时变为 18 了,也就不再理会这个 trigger,直到下一天的下午5点。 2)? 问号 ? 号只能用在日和周域上,但是不能在这两个域上同时使用。你可以认为 ? 字符是 "我并不关心在该域上是什么值。" 这不同于星号,星号是指示着该域上的每一个值。? 是说不为该域指定值。你为这两域的其中一个指定了值,那就必须在另一个字值上放一个 ?。
不能同时这两个域上指定值的理由是难以解释甚至是难以理解的。基本上,假定同时指定值的话,意义就会变得含混不清了:考虑一下,如果一个表达式在日域上有值11,同时在周域上指定了 WED。那么是要 trigger 仅在每个月的11号,且正好又是星期三那天被激发?还是在每个星期三的11号被激发呢?要去除这种不明确性的办法就是不能同时在这两个域上指定值。 表达式样例:0 10,44 14 ? 3 WEB
意义:在三月中的每个星期三的下午 2:10 和 下午 2:44 被触发。3), 逗号
逗号 (,) 是用来在给某个域上指定一个值列表的。例如,使用值 0,15,30,45 在秒域上意味着每15秒触发一个 trigger。表达式样例: 0 0,15,30,45 * * * ?
意义:每刻钟触发一次 trigger。4)/ 斜杠 斜杠 (/) 是用于时间表的递增的。我们刚刚用了逗号来表示每15分钟的递增,但是我们也能写成这样 0/15。 表达式样例: 0/15 0/30 * * * ?
意义:在整点和半点时每15秒触发 trigger。5)- 中划线 中划线 (-) 用于指定一个范围。例如,在小时域上的 3-8 意味着 "3,4,5,6,7 和 8 点。" 域的值不允许回卷,所以像 50-10 这样的值是不允许的。 表达式样例:0 45 3-8 ? * *
意义:在上午的3点至上午的8点的45分时触发 trigger。6)L 字母
L 说明了某域上允许的最后一个值。它仅被日和周域支持。当用在日域上,表示的是在月域上指定的月份的最后一天。例如,当月域上指定了 JAN 时,在日域上的 L 会促使 trigger 在1月31号被触发。假如月域上是 SEP,那么 L 会预示着在9月30号触发。换句话说,就是不管指定了哪个月,都是在相应月份的时最后一天触发 trigger。表达式 0 0 8 L * ?
意义是在每个月最后一天的上午 8:00 触发 trigger。在月域上的 * 说明是 "每个月"。 当 L 字母用于周域上,指示着周的最后一天,就是星期六 (或者数字7)。所以如果你需要在每个月的最后一个星期六下午的 11:59 触发 trigger,你可以用这样的表达式 0 59 23 ? * L。
当使用于周域上,你可以用一个数字与 L 连起来表示月份的最后一个星期 X。例如,表达式 0 0 12 ? * 2L 说的是在每个月的最后一个星期一触发 trigger。
不要让范围和列表值与 L 连用。虽然你能用星期数(1-7)与 L 连用,但是不允许你用一个范围值和列表值与 L 连用。这会产生不可预知的结果。7)W 字母
W 字符代表着*日 (Mon-Fri),并且仅能用于日域中。它用来指定离指定日的最*的一个*日。大部分的商业处理都是基于工作周的,所以 W 字符可能是非常重要的。例如,日域中的 15W 意味着 "离该月15号的最*一个*日。" 假如15号是星期六,那么 trigger 会在14号(星期四)触发,因为距15号最*的是星期一,这个例子中也会是17号(译者Unmi注:不会在17号触发的,如果是15W,可能会是在14号(15号是星期六)或者15号(15号是星期天)触发,也就是只能出现在邻*的一天,如果15号当天为*日直接就会当日执行)。W 只能用在指定的日域为单天,不能是范围或列表值。 8)井号井号字符仅能用于周域中。它用于指定月份中的第几周的哪一天。例如,如果你指定周域的值为 6#3,它意思是某月的第三个周五 (6=星期五,#3意味着月份中的第三周)。另一个例子 2#1 意思是某月的第一个星期一 (2=星期一,#1意味着月份中的第一周)。注意,假如你指定 #5,然而月份中没有第 5 周,那么该月不会触发。
例子:
表达式意义"0 0 12 * *?" 每天中午12点触发"0 15 10 ? **" 每天上午10:15触发"0 15 10 * *?" 每天上午10:15触发"0 15 10 * * ?*" 每天上午10:15触发"0 15 10 * * ?2005" 2005年的每天上午10:15触发"0 * 14 * *?" 在每天下午2点到下午2:59期间的每1分钟触发"0 0/5 14 * *?" 在每天下午2点到下午2:55期间的每5分钟触发"0 0/5 14,18 ** ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发"0 0-5 14 * *?" 在每天下午2点到下午2:05期间的每1分钟触发"0 10,44 14 ? 3WED" 每年三月的星期三的下午2:10和2:44触发"0 15 10 ? *MON-FRI" 周一至周五的上午10:15触发"0 15 10 15 *?" 每月15日上午10:15触发"0 15 10 L *?" 每月最后一日的上午10:15触发"0 15 10 ? *6L" 每月的最后一个星期五上午10:15触发"0 15 10 ? * 6L2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发"0 15 10 ? *6#3" 每月的第三个星期五上午10:15触发
3.参考文章
https://blog.csdn.net/chenmingxu438521/article/details/94485695
https://www.cnblogs.com/zhaobingqing/p/7449474.html
http://www.javashuo.com/article/p-dxpgfazn-bt.html


















