`
须等待
  • 浏览: 211026 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Quartz的使用心得

阅读更多

项目中要用到定时调度的功能,使用的是quartz,使用中遇到了一些问题,特地记下来。

一、quartz概述

quartz是一个任务定时调度的框架,支持定时的调用特定的方法,支持与Spring的整合。

二、配置步骤

quartz与Spring整合,需要一个配置文件来管理quartz中的类。

 

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
	<!-- 实际的工作Bean -->
	<bean id="workBean" class="WorkClass">
	</bean>
	<!-- jobBean用于设定启动时运用的Bean与方法 -->
	<bean id="scheduledReportJobDetail"
		class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject">
			<ref bean="workBean" />
		</property>
		<property name="targetMethod">
			<value>work</value>
		</property>
	</bean>
	<!-- 每5秒启动一次 -->
	<bean id="trigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail">
			<ref bean="scheduledReportJobDetail" />
		</property>
		<property name="cronExpression">
			<value> 0/5 * * * * ?</value>
		</property>
	</bean>
	<!-- 起动Bean -->
	<bean id="scheduler"
		class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
				<ref bean="trigger" />
			</list>
		</property>
	</bean>
</beans>
 

 

配置文件中配置的几个bean,依次代表,实际工作的bean、封装后用于调度的bean、配置有时间间隔的trigger触发器bean和用于启动任务的主类工厂bean。

这样,创建自己的调度就变得非常简单,我们只需要完成自己的工作方法,在xml中配置好,并制定一个时间间隔,然后启动主类就可以了。

 

public class WorkClass {
    public void work() {
        System.out.println("hello world");
    }

    public static void main(String[] args) {
        BeanFactory factory = new XmlBeanFactory(new ClassPathResource("scheduleTask.xml"));
        System.out.println(factory.getBean("scheduler"));
    }

}

 

    当然,除了和Spring整合之外,Quartz也可以单独用。

    同Spring中的工作类不一样,不用Spring的工作类需要继承Job接口。

 

public class TestWithoutSpring implements Job {

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("work");
    }
}
 

    而触发器和调度者的信息则需要在调用处指定。

 

public void testWork() {
        JobDetail jobDetail = new JobDetail(); 
        jobDetail.setJobClass(TestWithoutSpring.class); 
        jobDetail.setName("asdf");
        CronTrigger trigger = new CronTrigger();
        trigger.setName("test");
        String expression = "2-3 0/1 * * * ?";
        Scheduler scheduler = null;
        
        try {
            trigger.setCronExpression(expression);
            SchedulerFactory sf = new StdSchedulerFactory(); 
            scheduler = sf.getScheduler();
            scheduler.scheduleJob(jobDetail, trigger); 
            scheduler.start(); 
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        
    }

    启动以后就和使用Spring管理是一样的效果了。 

 

三、时间间隔配置

在触发器bean中有一个重要的属性叫cronExpression,这个是代表调度频率,也就是时间间隔的,这里有特殊的格式。

quartz中的时间格式有7个元素组成,分别为秒、分、时、日、月、周几、年(可选),反应在配置中就是7(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     , - * /

这里常规的配置就是直接输入数字,但是quartz允许我们使用更加泛化的配置,所以提供了一些通配符。

* 表示用于替代任意数字

/表示增加幅度, 5/10表示从5开始,每10执行一次

-表示一个区间范围

? 在日和周几中出现,这里是用来明确界定,以免产生歧义

 

如cronExpression配置为 0/5 * * * * * 时会报错:Support for specifying both a day-of-week AND a day-of-month parameter is not implemented, 这就是日和周几产生了冲突, 改为 0/5 * * * * ? 就可以了,表示每5秒执行一次任务。

 

P.S quartz一开始是没有和Spring做整合的而且随着版本的迭代个中的类有一些变化, 这里就要注意quartz和Spring的版本匹配问题。

 

四、深入

Spring管理的quartz类变得很抽象,实际上,quar中有几个核心的类。

Job接口,实现了Job接口的类是任务中的实际工作类,对应于workBean

JobDetail类,包装Job,对应于scheduledReportJobDetail,利用反射在实际的调度中执行特定的方法

Trigger类,这是触发器类,用于封装调度频率时间间隔的逻辑,对应于trigger

Scheduler类,这是调度类,是封装了整个调度逻辑的最高层抽象,它持有代表任务的JobDetail类和代表调度频率的Trigger类,是调度逻辑的执行者和管理者。

 

了解了主要的类,要执行管理就很简单了,比如要控制调度的暂停或者关闭,只要通过Spring拿到对应的Scheduler类,调用其方法就可以了

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics