版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/programlight/article/details/81737071
目录
概述
本文主要通过Spring和Quartz 实现定时任务
Spring是一个开源框架,强大之处就不多说了
Quartz是纯Java实现,而且是Spring的默认调度框架
Quartz具有强大的调度功能、灵活的使用方式、还具有分布式集群能力
可以说Quartz出马,可以搞定一切定时任务调度
Quartz的体系结构
Quartz有3个核心概念:调度器(Scheduler)、任务(Job&JobDetail)、触发器(Trigger)
(一个任务可以被多个触发器触发,一个触发器只能触发一个任务)
书写定时任务的类
可分为两种写法,继承QuartzJobBean
和不继承的,二者仅编写定时任务类和xml配置作业类两步不同
对于继承QuartzJobBean类的需要做:
- 需要实现定时任务的类继承org.springframework.scheduling.quartz.QuartzJobBean,实现定时执行的方法 xml里要么声明这个定时任务类,要么使用注解扫描的方式声明
- xml里声明新的bean,class为org.springframework.scheduling.quartz.JobDetailBean
<bean name="job" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.example.QuartzTimer" /> <!-- 指定定时任务类 -->
<property name="jobDataAsMap"><!-- 为定时任务类注入属性,注意对应定时任务类,需要有属性的set方法 -->
<map>
<entry key="timeout" value="0" />
</map>
</property>
</bean>
对于没继承QuartzJobBean类的需要做:
- 需要实现定时任务的类,主要是实现定时执行的方法
- xml里使用MethodInvokingJobDetailFactoryBean配置作业类
<bean id="job" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<bean class="com.example.QuartzTimer" /> <!-- 这个属性,指定定时任务类 -->
</property>
<property name="targetMethod" value="doJob" />
<property name="concurrent" value="false" /><!-- 作业不并发调度 -->
</bean>
XML里配置触发器Trigger
触发器分为两种:
- org.springframework.scheduling.quartz.SimpleTriggerBean 只支持按频率触发,比如每隔多长时间执行一次
- org.springframework.scheduling.quartz.CronTriggerBean 支持使用Cron表达式,指定类似“在每几天的什么时间执行”的触发
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="job" />
<property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 -->
<property name="repeatInterval" value="2000" /><!-- 每2秒调度一次 -->
</bean>
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="job" />
<!-- 每天12:00运行一次 -->
<property name="cronExpression" value="0 0 12 * * ?" />
</bean>
XML里配置调度工厂Scheduler
Scheduler是Quartz 调度程序的主要接口
Scheduler维护了一个JobDetails 和Triggers的注册表
一旦在Scheduler注册过了,当定时任务触发时间一到,调度程序就会负责执行预先定义的Job
<!-- 所有的触发器配到这里,由调度工厂统一调度 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleTrigger"/>
<ref bean="cronTrigger"/>
</list>
</property>
</bean>
Cron表达式
字段 | 允许值 | 允许的特殊字符 |
秒 (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 | , - * / 四个字符 |
每一个域都使用数字,但还可以出现如下特殊字符
- *:表示匹配该域的任意值。假如在Minutes域使用*, 即表示每分钟都会触发事件
- ?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会
- -:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次
- /:表示起始时间开始触发,然后每隔固定时间触发一次
- ,:表示列出枚举值
- L:表示最后,只能出现在DayofWeek和DayofMonth域
- W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件
- LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五
- #:用于确定每个月第几个星期几,只能出现在DayofMonth域
Cron表达式例子
- 0 0 2 1 * ? * 表示在每月的1日的凌晨2点调整任务
- 0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业
- 0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作
- 0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
- 0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
- 0 0 12 ? * WED 表示每个星期三中午12点
- 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触发