Spring中正确使用Quartz和CronExpression

Quartz作为企业级任务调度框架以其灵活的使用方式、强大的功能已经得到广泛应用,作为一向喜欢将业内流行的工具纳入支持的Spring自然已经内置了对Quartz的支持,使得Quartz中最常使用的SimpleTrigger和CronTrigger的使用得到了最大简化,分别对应Spring的org.springframework.scheduling.quartz.SimpleTriggerBean和org.springframework.scheduling.quartz.CronTriggerBean,这两个类用起来非常方便,其中SimpleTrigger更类似于JDK中的Timer,它只是简单的以某个时间间隔来执行某个任务而已,比较简陋,而CronTrigger功能则十分强大,可以设定制定任务在任意指定时刻内调用,其使用Unix中的Cron Expression来制定调度策略,十分灵活,不过Cron Expression可能需要用点时间来学习,不过一旦掌握会觉得真的很不错,掌握了这两种Trigger基本上就可以应付实现大多数J2EE应用中的时间任务调度服务了。
下面举一个简单例子说明一下在Spring1.2.5中使用Quartz1.5的方式(所需要的包在Spring1.2.5的发行版中的lib目录下可以找到,将其拷贝到工程的类路径中)。
首先建立两个要调度的任务,他们都必须继承自org.springframework.scheduling.quartz.QuartzJobBean,而业务逻辑都是放在executeInternal方法中,指定的任务逻辑实现之后,需要将其注入到一个JobDetailBean中,JobDetailBean可以看作为一个具体任务的设置它指定了要执行的任务和执行任务的时间策略,JobDetailBean不用实现,只需要在Spring的配置文件中设置便可:
package com.peuo.albumSys.scheduling;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.apache.log4j.Logger;
import com.peuo.albumSys.business.IAlbumSysService;
import com.peuo.albumSys.domainobj.User;
import com.peuo.albumSys.domainobj.Album;

public class ScheduledQueryUsers extends QuartzJobBean {
private static Logger log = Logger.getLogger(ScheduledQueryUsers.class);

private IAlbumSysService service = null;

public void setService(IAlbumSysService service) {
this.service = service;
}


protected void executeInternal(JobExecutionContext ctx)
throws JobExecutionException {
log.debug("Now entering method executeInternal()...");
List users = service.findAllUser();
StringBuffer str = new StringBuffer();
for(int i = 0; i < users.size(); i++){
User user = (User)users.get(i);
str.append("\nUser[" + i + "] = " + user.getUserName());
Set albums = user.getAlbumSet();
Iterator it = albums.iterator();
str.append("(Albums:");
while(it.hasNext()){
str.append(((Album)it.next()).getAlbumName()).append(";");
}
}
log.debug(str.toString());
}
}

package com.peuo.albumSys.scheduling;
import java.util.Date;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.apache.log4j.Logger;
import com.peuo.albumSys.business.IAlbumSysService;
import com.peuo.albumSys.domainobj.Album;
import com.peuo.albumSys.domainobj.Photo;

public class ScheduledAddPhoto extends QuartzJobBean {
private static Logger log = Logger.getLogger(ScheduledAddPhoto.class);

private IAlbumSysService service = null;
private static int count = 0;

protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
Date now = new Date(System.currentTimeMillis());
Photo newPhoto = new Photo();
newPhoto.setAlbum(new Album(new Integer(1)));
newPhoto.setPhotoName( now.toString());
newPhoto.setPhotoUrl("Photo url" + ++count);
service.addPhoto(newPhoto);
log.debug("New photo added : name =" + newPhoto.getPhotoName() +"; url = " + newPhoto.getPhotoUrl());
}

public IAlbumSysService getService() {
return service;
}

public void setService(IAlbumSysService service) {
this.service = service;
}
}
然后在Spring的配置文件中分别设置一个SimpleTriggerBean和CronTriggerBean来调用上面两个任务,配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
……………………………………………………………………………………………………
<bean id="queryUserJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>com.peuo.albumSys.scheduling.ScheduledQueryUsers</value>
</property>
<property name="jobDataAsMap">
<map>
<entry key="service">
<ref local="albumSysService"/>
</entry>
</map>
</property>
</bean>

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<ref local="queryUserJob"/>
</property>
<property name="startDelay">
<value>15000</value>
</property>
<property name="repeatInterval">
<value>60000</value>
</property>
<property name="repeatCount">
<value>-1</value>
</property>
</bean>

<bean id="addPhotoJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>com.peuo.albumSys.scheduling.ScheduledAddPhoto</value>
</property>
<property name="jobDataAsMap">
<map>
<entry key="service">
<ref local="albumSysService" />
</entry>
</map>
</property>
</bean>

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref local="addPhotoJob"/>
</property>
<property name="cronExpression">
<value>0 20 19 * * ?</value>
</property>
</bean>

<bean id="sfb" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="simpleTrigger"/>
<ref local="cronTrigger"/>
</list>
</property>
</bean>
上面红色标出的部分可以看出,Spring对于将QuartzJob注入JobDetailBean的方式有点特殊,你需要将要注入给QuartzJob的某个属性注入到JobDetailBean的jobDataAsMap中,这不同于Spring平时直接对某个Bean的属性直接注入的方式,这主要是因为Quartz执行一个任务(JOB或者叫作业)的时候会提供给任务一个JobExecutionContext的任务执行上下文,从这个上下文中可以获得Job的环境设置,具体的可以看一下Quartz的API文档就明白了,反正只要记住这里的注入方式比较特殊就行了。
以上配置文件分别设置了一个SimpleTriggerBean和CronTriggerBean,前者将会在程序执行15秒之后开始不断以间隔一分钟的方式不断查询当前用户信息并显示出来,后者则指定每天的19:20分执行向ID为1的用户的相册内添加一张照片的任务,其Cron Expression为0 20 19 * * ?。
从以上可以看出,Spring大大简化了对Quartz任务时间调度框架的使用,将其完美的融合入了Spring提供的IoC容器,只是其注入方式需要注意,还有就是Cron Expression一定要掌握,这个是Quartz真正的强大之处。

网上似乎对Cron表达式的中文介绍相当少,我干脆就把Quartz中的doc翻译一下,各位需要的朋友可以快速了解一下大致用法:
一个Cron-表达式是一个由六至七个字段组成由空格分隔的字符串,其中6个字段是必须的而一个是可选的,如下:
字段名 允许的值 允许的特殊字符
秒 0-59 , - * /
分 0-59 , - * /
小时 0-23 , - * /
日 1-31 , - * ? / L W C
月 1-12 or JAN-DEC , - * /
周几 1-7 or SUN-SAT , - * ? / L C #
年 (可选字段) empty, 1970-2099 , - * /

'*' 字符可以用于所有字段,在“分”字段中设为"*"表示"每一分钟"的含义。
'?' 字符可以用在“日”和“周几”字段. 它用来指定 '不明确的值'. 这在你需要指定这两个字段中的某一个值而不是另外一个的时候会被用到。在后面的例子中可以看到其含义。
'-' 字符被用来指定一个值的范围,比如在“小时”字段中设为"10-12"表示"10点到12点".
',' 字符指定数个值。比如在“周几”字段中设为"MON,WED,FRI"表示"the days Monday, Wednesday, and Friday".
'/' 字符用来指定一个值的的增加幅度. 比如在“秒”字段中设置为"0/15"表示"第0, 15, 30, 和 45秒"。而 "5/15"则表示"第5, 20, 35, 和 50". 在'/'前加"*"字符相当于指定从0秒开始. 每个字段都有一系列可以开始或结束的数值。对于“秒”和“分”字段来说,其数值范围为0到59,对于“小时”字段来说其为0到23, 对于“日”字段来说为0到31, 而对于“月”字段来说为1到12。"/"字段仅仅只是帮助你在允许的数值范围内从开始"第n"的值。 因此 对于“月”字段来说"7/6"只是表示7月被开启而不是“每六个月”, 请注意其中微妙的差别。
'L'字符可用在“日”和“周几”这两个字段。它是"last"的缩写, 但是在这两个字段中有不同的含义。例如,“日”字段中的"L"表示"一个月中的最后一天" —— 对于一月就是31号对于二月来说就是28号(非闰年)。而在“周几”字段中, 它简单的表示"7" or "SAT",但是如果在“周几”字段中使用时跟在某个数字之后, 它表示"该月最后一个星期×" —— 比如"6L"表示"该月最后一个周五"。当使用'L'选项时,指定确定的列表或者范围非常重要,否则你会被结果搞糊涂的。
'W' 可用于“日”字段。用来指定历给定日期最近的工作日(周一到周五) 。比如你将“日”字段设为"15W",意为: "离该月15号最近的工作日"。因此如果15号为周六,触发器会在14号即周五调用。如果15号为周日, 触发器会在16号也就是周一触发。如果15号为周二,那么当天就会触发。然而如果你将“日”字段设为"1W", 而一号又是周六, 触发器会于下周一也就是当月的3号触发,因为它不会越过当月的值的范围边界。'W'字符只能用于“日”字段的值为单独的一天而不是一系列值的时候。
'L'和'W'可以组合用于“日”字段表示为'LW',意为"该月最后一个工作日"。
'#' 字符可用于“周几”字段。该字符表示“该月第几个周×”,比如"6#3"表示该月第三个周五( 6表示周五而"#3"该月第三个)。再比如: "2#1" = 表示该月第一个周一而 "4#5" = 该月第五个周三。注意如果你指定"#5"该月没有第五个“周×”,该月是不会触发的。
'C' 字符可用于“日”和“周几”字段,它是"calendar"的缩写。 它表示为基于相关的日历所计算出的值(如果有的话)。如果没有关联的日历, 那它等同于包含全部日历。“日”字段值为"5C"表示"日历中的第一天或者5号以后",“周几”字段值为"1C"则表示"日历中的第一天或者周日以后"。
对于“月份”字段和“周几”字段来说合法的字符都不是大小写敏感的。
下面是一些完整的例子:
表达式 含义
"0 0 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分每分钟一次触发
"0 0/5 14 * * ?" 每天从下午2点开始到2:55分结束每5分钟一次触发
"0 0/5 14,18 * * ?" 每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发
"0 0-5 14 * * ?" 每天14:00至14:05每分钟一次触发
"0 10,44 14 ? 3 WED" 三月的每周三的14:10和14:44触发
"0 15 10 ? * MON-FRI" 每个周一、周二、周三、周四、周五的10:15触发
"0 15 10 15 * ?"
神经网络:初学者指南(专业版) 神经网络是一种受生物大脑启发的计算模型,由多层互连的人工神经元组成。本文从生物神经元结构出发,介绍了感知器模型、激活函数、网络架构(输入/隐藏/输出层)等基础概念,并详细阐述了前向传播、反向传播、损失函数和优化器等核心训练机制。同时涵盖了CNN、RNN等常见架构,以及过拟合、梯度消失等关键挑战,最后概述了神经网络在计算机视觉、NLP等领域的广泛应用。全文系统性地梳理了神经网络的基础理论和实践要点,为初学者提供了清晰的学习路径。 阅读详情

相关推荐

海思Hi3559A/CV100 DDR4参数配置经验分享

海思Hi3559A/CV100 DDR4参数配置方法 Hi3559AV100 DDR4 驱动配置说明 1.1 Hi3559AV100 DDR4 CLK/AC 驱动配置方法 寄存器地址 DDR PHY0:0x1206d0bc DDR PHY1:0x1206f0bc 寄存器描述 − Bit[5:3]:CLK 驱动 − Bit[14:12]:2T 驱动 − Bit[20:18]:1T 驱动 驱动大小定义 − 000:Disable − 001:240ohm − 010: 120ohm − 011:80ohm −

WeChat_zhanggong345的博客 2878

java定时任务自由配置_定时任务:Quartz 在 Spring 中如何动态配置时间

在项目中有一个需求,需要灵活配置调度任务时间,并能自由启动或停止调度。有关调度的实现我就第一就想到了Quartz这个开源调度组件,因为很多项目使用过,Spring结合Quartz静态配置调度任务时间,非常easy。比如:每天凌晨几点定时运行一个程序,这只要在工程中的spring配置文件中配置好spring整合quartz的几个属性就好。Spring配置文件Xml代码 这种配置就是对quartz的一...

weixin_30199299的博客 1500

Masta调用Geometry Modeller(Space Claim)进行根据三维模型快速建模设置方法

masta中调用ANSYS的space claim的设置方法

xifegnlie的博客 239

SpringBoot2.0集成Quartz实现动态定时任务

多任务情况下,quartz更容易管理,可以实现动态配置  执行时间表达式:  表达式示例:  微服务启动时 必须加上@EnableScheduling 下面是单纯schedule 用法,简单 @Scheduled(cron="0/5 * * * * ?") public void job(){ System.out.println("每五秒执行一次"); ...

LMC技术人生专栏 4472

单细胞数据pseudobulks差异分析实战:从聚合到DESeq2

本文详细介绍了单细胞转录组数据分析中pseudobulks(伪散装)方法的实战流程。通过将同一样本的同类型细胞表达值聚合,模拟Bulk RNA-seq数据,再利用DESeq2进行稳健的差异基因分析。该方法有效降低了单细胞数据的技术噪音,特别适用于样本量有限但追求结果稳定性的研究场景,并提供了完整的R代码实现与结果解读指南。

sea99的博客 758

《涨知识啦29》-DBR的工作原理及其在VCSEL中的作用

分布式布拉格(Distributed Bragg Reflection,简称DBR)反射镜是垂直腔面发射激光器(Vertical-Cavity Surface-Emitting Laser,简称VCSEL)的重要组成部分。典型的DBR反射镜是由1/4ni波长厚度的高折射率和低折射率材料交替组成(ni是该层的折射率)。其反射率取决于组成对数、边界条件以及折射率差。 图1 布拉格反射镜的工作原理 DBR反射镜的工作原理如图1所示。根据反射原理,当光从光疏介质n1射向光密介质n2(折射率n2>n1)时,反

simucal的博客 7981

Java代码判断cron表达式是否有效(案例详解)

手把手教学分享Java代码判断cron表达式是否有效!

末尾卡片和博主交流学习! 3735

大模型系列——Ollama简明教程

在这篇文章中,我们将了解如何使用 Ollama、如何在 Ollama 中创建自己的模型 以及如何使用 Ollama 构建聊天机器人。这是深入研究 Ollama 的第一部分,以及我所学到的有关本地 LLM 的知识以及如何将它们用于基于推理的应用程序。在这篇文章中,你将了解——

2401_84052244的博客 1万+

[开发|java] org.quartz 使用cron表达式

org.quartz 是一个开源的任务调度框架,用于在Java应用程序中实现任务的定时执行。它支持多种触发器类型,其中一种是使用 cron 表达式进行任务调度。

梦醒贰零壹柒 709

【系列05】端侧AI:构建与部署高效的本地化AI模型 第4章:模型量化(Quantization)

量化的基本思想是减少模型中用于表示参数和激活值的比特数。在模型训练时,参数通常使用32位浮点数(FP32)进行存储,这提供了高精度,但也消耗大量的内存和计算资源。量化则将这些32位浮点数转换成低比特数表示,通常是8位整数(INT8)。量化的原理可以概括为:对浮点数范围进行校准,并将其映射到更小的整数范围内。例如,将一个FP32的权重(如-1.5到1.5)映射到INT8的范围(-128到127)。在推理过程中,模型将使用这些低精度的整数进行计算,从而大大减少了所需的计算量。量化带来的主要收益减少模型大小。

学习,输出==》再学习再输出 1212

YOLO11涨点优化:原创自研 | 魔改Bottleneck,具备多尺度和特征通道融合的结构

可以将C3k2_MSAMCS放在neck,或者backbone和neck同时修改,具体看自己数据集的涨点情况决定

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1646

Spring中正确使用Quartz和CronExpression 执行策略

Quartz作为企业级任务调度框架以其灵活的使用方式、强大的功能已经得到广泛应用,作为一向喜欢将业内流行的工具纳入支持的Spring自然已经内置了对Quartz的支持,使得Quartz中最常使用的SimpleTrigger和CronTrigger的使用得到了最大简化,分别对应Spring的org.springframework.scheduling.quartz.SimpleTriggerBean

jinpengaigo929的专栏 1083

【ESP 保姆级教程】玩转emqx数据集成篇④ ——数据桥接之HTTP服务

主要是学习数据桥接功能以及构建自己的http服务器,这是一个非常有用的功能。包括各种传感器上报基本上都需要数据桥接功能支持,所以还是希望认真学习这一块开发,然后结合数据库存储等等知识点进行进一步学习。

单片机菜鸟哥的博客 1306

Spring--quartz中cronExpression

转自:http://dogstar.iteye.com/blog/116130 actoryBean">                                                     class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

xuanjiewu的专栏 995

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

java crontriggerbean,测试Quartz CronTrigger触发器

Assuming that I have a CronTriggerBean similar toWhat is the best way to test that this bean will actually trigger at its specified date, i.e. on the weekday closest to the 15th of each month at 6 AM?...

weixin_35752122的博客 215

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Quartz在Spring中动态设置cronExpression

版权所有:(xiaodaoxiaodao)蓝小刀    xiaodaoxiaodao@gmail.com http://www.blogjava.net/xiaodaoxiaodao/articles/103437.html         转载请注明来源/作者   Quartz 在Spring中动态设置cronExpression 什么是动态定时任务:是由客户制定生成的,服务

圣彼得堡之光的专栏 8523

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: eclipse编译时排除指定的文件或文件夹
下一篇: JDK 6 中文文档.
java_doom
博客等级 码龄20年 6粉丝 199原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值