调度器(Quartz)

孤人 提交于 2019-11-28 23:01:34

任务调度的时机(背景)

        例如在开发购物网站时会遇到一个问题,因白天订单多流量大,为减轻网站压力要求一些不是太急的任务(如给注册用户发送广告邮件、清理日常垃圾信息等)放在凌晨流量较小时间段去执行,这个时候就需要使用到任务调度,指定在某个时间内执行某个任务

任务调度实现方式

  • 借助java.util.Timer来实现的。对于更加复杂任务调度,Timer不太容易(定时器)
  • 使用Spring的Quartz调度器可弥补Timer的不足,使开发者能完成各种复杂任务调度(调度器)

spring调度器(Quartz)

介绍

        Quartz调度器为调度工作提供更丰富的支持,与Java定时器一样,可使用Quartz指定每隔多少毫秒执行一个工作,但Quartz比Java的Timer优势在于Quartz允许调度一个工作在某个特定的时间或日期执行。

使用Quartz有两种方式实现

  • 任务类继承QuartzJobBean
  • 在配置文件中定义任务类和要执行的方法(借助:MethodInvokingJobDetailFactoryBean)

Spring实现调度器基本步骤

第一步:创建一个用于指定执行任务的QuartzJobBean子类

        QuartzJobBean实现org.quartz.Job接口。QuartzJobBean子类应当覆盖executeInternal()方法,在executeInternal()方法中定义预定的时刻应执行动作(这一步是指明做什么)

参考代码如下:CustomerQuartzJobBean.java

package www.enfp.cc.springquartz;

import java.util.Date;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class CustomerQuartzJobBean extends QuartzJobBean
{

	@Override
	protected void executeInternal(JobExecutionContext arg0)
			throws JobExecutionException
	{
		//指定需要执行的任务,这里仅仅是输出当前时间
		System.out.println("执行调度任务: (当前时间:" + new Date() + ")");
	}
}

第二步:在配置文件中进行调度器的相关配置(beans.xml)

1.配置执行工作<做什么>

        JobDetailBean是Quartz的JobDetail的子类,通过jobClass属性来设置一个Job对象,将第一步的QuartzJobBean的子类的全路径传给JobDetailBean的jobClass属性

参考代码如下:

<!-- 配置执行工作(做什么) -->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
	<property name="jobClass">
		<value>www.enfp.cc.springquartz.CustomerQuartzJobBean</value>
	</property>
</bean>

2.触发器Trigger的配置(配置执行时间和执行哪个工作)<什么时间做什么>

        Quartz的Trigger类描述了调度时机和频度,Spring提供了两个触发器:SimpleTriggerBean、CronTriggerBean。

  • SimpleTriggerBean用来指定一个工作运行频度,以及(可选地)在第一次运行之前等待时间。缺点是该触发器只能指定工作执行频度,而不能准确指定何时运行
  • CronTriggerBean能更精确地控制任务的运行时间。如每晚8点发送电子邮件。

(1).使用SimpleTriggerBean调度器(属性)介绍

  • jobDetail:定义工作(做什么)
  • startDelay:服务启动后的时间延迟,单位毫秒
  • repeatInterval:重复执行任务的时间间隔,单位毫秒

参考代码如下:

<!-- 执行效果:启动任务6秒后执行任务,并且每个4秒执行一次 -->
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
	<!-- 指定任务(做什么) -->
	<property name="jobDetail">
		<ref bean="jobDetail" />
	</property>
	<!-- 服务启动后延迟多少时间执行,单位毫秒 -->
	<property name="startDelay" value="6000"></property>
	<!-- 重复执行任务的时间间隔,单位毫秒 -->
	<property name="repeatInterval" value="4000"></property>
</bean>

(2).使用CronTriggerBean调度器(属性)介绍

  • jobDetail:定义工作(做什么)
  • cronExpression:cron表达式(指定执行时间)

     一个cron表达式有至少6个(也可能是7个)由空格分隔的时间元素。从左至右,这些元素的定义如下

  •     参数1:秒  0 - 59
  •     参数2:分钟  0-59
  •     参数3:小时  0-23
  •     参数4:月份中的日期  1-31
  •     参数5:月份 1-12或JAN-DEC
  •     参数6:星期中的日期 1-7或SUN-SAT
  •     参数7:年份1970-2099

    注意: 每一个元素都可显式规定一个值(如6),一个区间(如9-12),一个列表(如9,11,13)或一个通配符(如*)。“月份中的日期”和“星期中的日期”互斥,应通过设置一个问号(?)来表明你不想设置的那个字段

参考代码如下:

<!-- (触发器的配置)配置执行时间(或间隔)和执行哪个工作(什么时间做什么) -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
	<!-- (做哪个工作) -->
	<property name="jobDetail" ref="jobDetail"></property>
	<!-- 配置cron表达式(什么时间做) -->
	<property name="cronExpression" value="0 * 11 * * ?"></property>
</bean>

(3).启动触发器

       使用Spring的SchedulerFactoryBean类可使用list表示启动多个触发器

参考代码如下:

<!-- 启动触发器 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	<property name="triggers">
		<!-- 可以启动多个触发器,所以采用list标签 -->
		<list>
			<ref bean="cronTrigger"/>
		</list>
	</property>
</bean>

第三步:测试

1.web应用中使用(在web.xml文件加载beans.xml)

2.在java 应用中使用ClassPathXmlApplicationContext类加载beans.xml

参考代码如下:SpringQuartzTest.java

package www.enfp.cc.springquartz;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringQuartzTest
{
	public static void main(String[] args)
	{
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
				"beans.xml");
	}
}

补充:

 常见一些cron表达式的例子:

  • "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触发
  • 每天早上6点
  • 0 6 * * *
  • 每两个小时
  • 0 */2 * * *
  • 晚上11点到早上8点之间每两个小时,早上八点
  • 0 23-7/2,8 * * *
  • 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
  • 0 11 4 * 1-3
  • 1月1日早上4点
  • 0 4 1 1 *
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!