Spring 자체는 작업 스케줄링의 직접적인 구현을 제공하지 않지만 Spring은 자체 프레임 워크 원칙을 전제로 Timer와 Quartz의 통합을 제공합니다. 스프링 컨테이너를 사용하면 기존 Bean에 대한 작업을 쉽게 예약 할 수 있습니다.
봄에 작업 스케줄링을 사용하는 방법을 설명하기 전에 먼저 타이머 자체를 살펴 보겠습니다.
JDK에서 제공하는 Timer는 Quartz보다 더 간단한 스케줄링 방법이며 Quartz는 더 강력한 기능을 제공합니다. Timer에 비해 Quartz의 고유 한 기능은 다음과 같습니다.
1. 지속적인 작업을 지원합니다. Quartz를 사용하면 작업 상태를 유지할 수 있으며 애플리케이션 서버를 다시 시작할 때도 일관된 작업 상태를 유지할 수 있습니다.
2. 크론과 같은 타이밍 지원. Quartz의 CronTrigger를 통해 Quartz는 작업이 실행되는시기를 지정하기 위해 Unix와 유사한 스케줄링 방법을 사용할 수 있도록합니다. 타이머는 시간 및 간격 사양의 구현 만 허용합니다.
3. 스레드 처리 모델. Timer는 단일 스레드를 사용하여 작업을 구현하는 반면 Quartz는 스레드 풀을 사용하여 작업을 실행합니다. 스레드 풀의 크기와 구현은 Quartz 속성으로 지정할 수 있습니다.
4. 스케줄러, 트리거 및 작업을 포함하여 스케줄링 시스템의 모든 측면을 모니터링하기위한 성숙한 이벤트 모델을 제공합니다.
5. 또한 Quartz는 작업이 정상적으로 활성화되지 않았을 때 수행 할 작업을 지정하는 오발 명령을 제공합니다. 플러그인 지원이 제공되고 초기화를 위해 서블릿이 제공됩니다.
Spring은이 두 가지 스케줄링 메커니즘을 지원하는 일관된 방법을 제공합니다.
1) 먼저 Timer를 살펴 봅니다. Spring에서 Timer를 사용하는 것은 원래 Eco Timer를 사용하는 것과 다릅니다. 봄에서 가장 쉬운 방법은 MethodInvokingTimerTaskFactoryBean 메서드를 사용하여 작업을 생성하는 것입니다. 구성은 다음과 같습니다.
<bean id = "methodInvokingTask"class = "org.springframework.scheduling.timer.MethodI / nvokingTimerTaskFactoryBean">
<property name = "targetObject"> <ref bean = "exampleBusinessObject"/> </ property>
<property name = "targetMethod"> <value> 할 일 </ value> </ property>
</ bean>
위의 구성은 TimerTask를 생성하고 exampleBusinessObject의 idoSomething을 호출합니다.
다음으로 구성해야 할 것은 timerTask의 스케줄링 전략입니다.
<bean id = "scheduledTask"class = "org.springframework.scheduling.timer.ScheduledTimerTask">
<property name = "delay">
<값> 60000 </ 값>
</ property>
<property name = "period">
<값> 60000 </ 값>
</ property>
<property name = "timerTask">
<ref bean = "methodInvokingTask"/>
</ property>
</ bean>
위의 두 구성은 실행할 작업과 실행시기를 지정하며 이제 이러한 작업을 예약해야합니다.
<bean id="timerFactory" class="org.spring.framework.Scheduling.timer.TimerFactoryBean">
<property name="ScheduledTimerTask">
<list>
<ref local="ScheduledTask"/>
</list>
</property>
</bean>
TimerFactoryBean允许多个ScheduledTask,它会创建和管理Timer实例。
我们除了使用methodInvokingTask这种非侵入方式的TimeTask而外,我们还可以使用自己定义的TimerTask。
Package org.springframework.prospring.scheduling;
public class CustomTask extends TimerTask{
public void run(){// do something}
}
然后直接以spring bean方式配置,替换methodInvokingTask。
2)然后来看看使用Quartz对上述任务的配置。
<bean id="methodInvokingJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject"> <ref bean="exampleBusinessObject"/></property>
<property name="targetMethod"> <value>doSomething</value></property>
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="startDelay"><value>6000</value></property>
<property name="repeatInterval"><value>6000</value></property>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list><ref local="simpleTrigger"/></list>
</property>
</bean>
在Timer中只有两个概念TimerTask和Timer,至于调度细节是通过重载Timer的schedule方法来制定,只是在spring集成中spring将其分解成为了三个步骤。而Quartz确有四个概念,Scheduler(调度器)Trigger(触发器)Job(任务)JobDetail(工作细节),接下来详细来看这四个元素,以及spring对它们的支持:
job
job是具体任务的实现,需要继承自QuartzJobBean并在executeInternal方法中实现具体的任务细节。该方法接受一个参数,JobExcutionContext,其中包含了几乎所有信息的引用,以及需要存放的数据,以供在作业执行之间传递信息。实例代码如下:
package org.springframework.prospring.scheduling;
public class ExampleJob extends QuartzJobBean{
private long lastExecutionDate;
public void setListExecutionDate(long lastExecutionDate){
this.lastExecutionDate = lastExecutionDate;
}
protected void executeInternal(JobExcutionContext context){
//do some thing
// read or write data
JobDataMap map = context,getJobDetail().getJobDataMap();
map.put(”lastExecutionDate",System.currentTimeMills());
}
}
该类的初始化时在Quartz中进行的,需要首先包裹在JobDetail中,JobDetail中负责持有当前任务的相关默认数据。配置如下
<bean id="exampleJobBean" class="org.springframework.quartz.JobDetailBean">
<property name="name"><value>example</value>
<property name="group"><value>examples</value>
......
<property name="jobClass">
<value>org.springframework.prospring.scheduling.ExampleJob</value>
</property>
<bean>
触发器,触发器中描述了作业的触发策略。之前的例子中已经提到一种方式,其实Quartz提供了两种方式触发器,simple和cron。cron使用类似于Unix中的调度描述表达式,配置如下:
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="exampleJobDetail"/>
</property>
<property name="cronExpression">
<value>0 15 4 ? * MON-FRI</value>
</property>
<bean>
触发器中还可以指定哑火指令,指定监听器。
调度器,作为Quartz系统的主要部分,它维护了所有的作业细节和关联触发器的一个注册项;它在作业被激活的时候,它管理作业的创建和运行,并且负责保持作业的状态信息。
Spring本身不提供任务调度的直接实现,但是Spring在自身框架原则前提下提供了对Timer和Quartz的集成。使用spring容器可以轻松地对既有的bean进行任务调度。
在说明如何在spring中使用任务调度之前,首先来看看Timer本身。
JDK中提供的Timer是比Quartz更为简单的调度方法,当然,Quartz提供了更为强大的功能。相比Timer,Quartz独有的特性包括:
1、支持持久性作业。Quartz允许将作业状态持久化,在应用服务器重启之间,也能够保持一致的作业状态。
2、类Cron的定时支持。通过Quartz的CronTrigger,Quartz允许使用类似Unix调度的方式来制定作业何时执行。而Timer只允许执行时间和间隔的规范。
3、线程处理模型。Timer是使用单线程实现作业,而Quartz使用线程池来执行作业。线程池的大小以及实现都可以用Quartz属性来制定。
4、提供成熟的事件模型,用于监控调度系统的各个方面包括调度器,触发器和作业。
5、另外Quartz还提供了哑火指令用于指定当任务没有正常激活该做什么。提供了插件支持,提供了servlet用以初始化。
Spring提供了一致的方式来支持这两种调度机制。
1)首先来看Timer,在spring中使用Timer与使用原生态的Timer有所不同,在spring最简单的方法就是使用MethodInvokingTimerTaskFactoryBean方法来创建任务,配置如下
<bean id="methodInvokingTask" class="org.springframework.scheduling.timer.MethodI/nvokingTimerTaskFactoryBean">
<property name="targetObject"> <ref bean="exampleBusinessObject"/></property>
<property name="targetMethod"> <value>doSomething</value></property>
</bean>
以上的配置就会创建一个TimerTask,调用exampleBusinessObject的idoSomething。
接下来需要配置的是该timerTask的调度策略:
<bean id="scheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay">
<value>60000</value>
</property>
<property name="period">
<value>60000</value>
</property>
<property name="timerTask">
<ref bean="methodInvokingTask"/>
</property>
</bean>
以上两个配置指定了要运行什么任务,何时运行,现在还需要预定这些任务:
<bean id="timerFactory" class="org.spring.framework.Scheduling.timer.TimerFactoryBean">
<property name="ScheduledTimerTask">
<list>
<ref local="ScheduledTask"/>
</list>
</property>
</bean>
TimerFactoryBean允许多个ScheduledTask,它会创建和管理Timer实例。
我们除了使用methodInvokingTask这种非侵入方式的TimeTask而外,我们还可以使用自己定义的TimerTask。
Package org.springframework.prospring.scheduling;
public class CustomTask extends TimerTask{
public void run(){// do something}
}
然后直接以spring bean方式配置,替换methodInvokingTask。
2)然后来看看使用Quartz对上述任务的配置。
<bean id="methodInvokingJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject"> <ref bean="exampleBusinessObject"/></property>
<property name="targetMethod"> <value>doSomething</value></property>
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="startDelay"><value>6000</value></property>
<property name="repeatInterval"><value>6000</value></property>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list><ref local="simpleTrigger"/></list>
</property>
</bean>
在Timer中只有两个概念TimerTask和Timer,至于调度细节是通过重载Timer的schedule方法来制定,只是在spring集成中spring将其分解成为了三个步骤。而Quartz确有四个概念,Scheduler(调度器)Trigger(触发器)Job(任务)JobDetail(工作细节),接下来详细来看这四个元素,以及spring对它们的支持:
job
job是具体任务的实现,需要继承自QuartzJobBean并在executeInternal方法中实现具体的任务细节。该方法接受一个参数,JobExcutionContext,其中包含了几乎所有信息的引用,以及需要存放的数据,以供在作业执行之间传递信息。实例代码如下:
package org.springframework.prospring.scheduling;
public class ExampleJob extends QuartzJobBean{
private long lastExecutionDate;
public void setListExecutionDate(long lastExecutionDate){
this.lastExecutionDate = lastExecutionDate;
}
protected void executeInternal(JobExcutionContext context){
//do some thing
// read or write data
JobDataMap map = context,getJobDetail().getJobDataMap();
map.put(”lastExecutionDate",System.currentTimeMills());
}
}
该类的初始化时在Quartz中进行的,需要首先包裹在JobDetail中,JobDetail中负责持有当前任务的相关默认数据。配置如下
<bean id="exampleJobBean" class="org.springframework.quartz.JobDetailBean">
<property name="name"><value>example</value>
<property name="group"><value>examples</value>
......
<property name="jobClass">
<value>org.springframework.prospring.scheduling.ExampleJob</value>
</property>
<bean>
触发器,触发器中描述了作业的触发策略。之前的例子中已经提到一种方式,其实Quartz提供了两种方式触发器,simple和cron。cron使用类似于Unix中的调度描述表达式,配置如下:
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="exampleJobDetail"/>
</property>
<property name="cronExpression">
<value>0 15 4 ? * MON-FRI</value>
</property>
<bean>
触发器中还可以指定哑火指令,指定监听器。
调度器,作为Quartz系统的主要部分,它维护了所有的作业细节和关联触发器的一个注册项;它在作业被激活的时候,它管理作业的创建和运行,并且负责保持作业的状态信息。