这几天都在准备面试,发现很多知识点和技术自己用过但没有好好总结,只是在云笔记里零乱记录了一下,有点茶壶煮饺子有货吐不出的感觉,尴尬~,这次决定遇到一个就总结一个。本文主要总结了一下spring quartz(包括带线程池和不带线程池版本、cron表达式规则)和基于@Scheduled注解的spring定时任务。
本文源码已上传GitHub:https://github.com/leon2016/egg.git
org.quartz-scheduler
quartz
${quartzVersion}
org.quartz-scheduler
quartz-jobs
${quartzVersion}
org.springframework
spring-context-support
${springVersion}
我的pom.xml (仅做出现问题参考,因为里面有很多其他用处的依赖):
4.0.0
com.leon
egg
war
0.0.1-SNAPSHOT
egg Maven Webapp
http://maven.apache.org
UTF-8
1.7
3.1
2.3
1.2
2.5
4.3.1.RELEASE
2.5.0
4.3.5.Final
5.1.24
0.9.1.2
1.2.20
4.4.1
2.2.1
1.6.1
1.4.7
1.2.17
junit
junit
4.1
test
jstl
jstl
${jstlVersion}
javax.servlet
servlet-api
${servletVersion}
provided
org.springframework
spring-beans
${springVersion}
org.springframework
spring-core
${springVersion}
org.springframework
spring-context
${springVersion}
org.springframework
spring-orm
${springVersion}
org.springframework
spring-context-support
${springVersion}
org.springframework
spring-web
${springVersion}
org.springframework
spring-webmvc
${springVersion}
com.fasterxml.jackson.core
jackson-core
${jacksonVersion}
com.fasterxml.jackson.core
jackson-databind
${jacksonVersion}
org.hibernate
hibernate-core
${hibernateVersion}
mysql
mysql-connector-java
${mysqlVersion}
c3p0
c3p0
${c3p0Version}
com.alibaba
fastjson
${fastjsonVersion}
org.apache.httpcomponents
httpclient
${apacheHttpVersion}
org.apache.httpcomponents
httpcore
${apacheHttpVersion}
org.quartz-scheduler
quartz
${quartzVersion}
org.quartz-scheduler
quartz-jobs
${quartzVersion}
org.apache.directory.studio
org.dom4j.dom4j
${dom4jVersion}
com.thoughtworks.xstream
xstream
${xstreamVersion}
log4j
log4j
${log4jVersion}
org.apache.commons
commons-lang3
3.3.2
org.springframework
spring-aop
${springVersion}
org.springframework
spring-aspects
${springVersion}
org.springframework
spring-tx
${springVersion}
maven-compiler-plugin
${mavenCompilerPluginVersion}
${jdkVersion}
${jdkVersion}
${encodeType}
egg
在Spring中使用Quartz有两种方式实现:第一种是任务类继承QuartzJobBean,第二种则是在配置文件里定义任务类和要执行的方法,类和方法仍然是普通类。
很显然,第二种方式远比第一种方式来的灵活,本文只介绍第二种。
如下:是我的一个获取微信token和ticket的定时任务类。
package com.leon.wx.task;
import org.apache.log4j.Logger;
import com.leon.wx.util.WeChatTask;
public class QuartzJob {
private static Logger logger = Logger.getLogger(QuartzJob.class);
/**
* @Description: 定时任务执行获取 token
* @param
*/
public static void workForToken() {
logger.info("开始执行定时任务workForToken...");
try {
WeChatTask.getToken_getTicket();
} catch (Exception e) {
e.printStackTrace();
}
logger.info("定时任务workForToken执行完毕。");
}
}
新建在spring-quartz.xml(和spring配置文件放同一个位置):不同位置也可通过
在spring配置文件中引入quartz配置文件。
spring-quartz.xml如下: 配置 1,2,3(可选),4。
workForToken
0 0/60 * * * ?
使用调度器Quartz来进行数据归档的时候,当我们开的定时任务很多的时候,就会出现一些定时任务不会被触发的现象,这就是线程阻塞。那到底什么叫线程阻塞呢?
线程阻塞,顾名思义就是说线程被阻塞了,没有按时执行,即定时任务没有被触发。那么为什么会出现中定时任务没被触发的现象呢?
通过对调取器的调度原理的分析,我们可以知道:当正在执行的调度任务个数超过了调度器中设置的最大值时,就会出线程阻塞,调度任务延迟执行的现象。
--摘自 https://blog.csdn.net/ghgzczxcvxv/article/details/44457833
在上面不带线程池版本上,在spring-quartz.xml添加下列配置即可实现带线程池版本的quartz定时任务。
完整spring-quartz.xml:
workForToken
0 0/60 * * * ?
在spring配置文件中:
(1)添加命名空间
// 1.xmlns添加:
xmlns:task="http://www.springframework.org/schema/task"
// 2.xsi:schemaLocation添加:
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
(2)启用注解驱动的定时任务
(3)配置定时任务的线程池(可选)
tip:推荐配置线程池,同quartz中配置线程池原因,若不配置多任务下会出现线程阻塞,导致定时任务无法正常执行。
这里我直接修改上面quartz的任务类实现同样定时任务:
package com.leon.wx.task;
import org.apache.log4j.Logger;
import com.leon.wx.util.WeChatTask;
public class Job {
private static Logger logger = Logger.getLogger(QuartzJob.class);
/**
* @Description: 定时任务执行获取 token
* @param
*/
@Scheduled(cron="0 0/60 * * * ?") //每小时执行一次
public static void workForToken() {
logger.info("开始执行定时任务workForToken...");
try {
WeChatTask.getToken_getTicket();
} catch (Exception e) {
e.printStackTrace();
}
logger.info("定时任务workForToken执行完毕。");
}
}
这篇文章写道比较好:Quartz和Spring Task定时任务的简单应用和比较
我的结论是:总的来说,Quartz包含Spring Task:@Schedule所有功能,推荐使用Quartz。
需要注意的是,对异常的处理,两者有较大区别,需要按需选用:
字段 | 允许值 | 允许的特殊字符 |
---|---|---|
秒 | 0-59 | ,- * / |
分 | 0-59 | , - * / |
小时 | 0-23 | ,- * / |
日期 | 1-31 | ,- * ? / L W C |
月份 | 1-12 或者 JAN-DEC | ,- * / |
星期 | 1-7 或者 SUN-SAT | ,- * ? / L C # |
年(可选) | 留空,1970-2099 | , - * / |
好记性不如烂笔头啊~~
corn表达式 | 含义 |
---|---|
0/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 ? 3 WED” | 每年三月的星期三的下午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 ? * 6L 2002-2005” | 2002年至2005年的每月的最后一个星期五上午10:15触发 |
“0 15 10 ? * 6#3” | 每月的第三个星期五上午10:15触发 |
https://www.cnblogs.com/hongwz/p/5642429.html
https://blog.csdn.net/tby415/article/details/80180692
https://www.cnblogs.com/kxxiang/p/4297535.html
https://www.cnblogs.com/marvinn/p/10563640.html
https://blog.csdn.net/zp437734552/article/details/51899275/