1. Overview
为了降低使用Quartz的难度,并能以Spring风格的方式使用Quartz,Spring为Quartz提供了Scheduler, Trigger, JobDetail的FactoryBean类,以及一些工具类,使Quartz能很好的注入容器,并可以结合Spring容器的生命周期,启动和关闭job。
2. JobDetailBean
使用JobDetailBean,需要设置其JobClass属性,指定实现了Job接口的实现类。JobDetailBean默认使用bean名作为job名,DEFAULT作为组名,并可以通过applicationContextJobDataKey键,将ApplicationContext设置到JobDataMap中。JobDetailBean支持以Map方式设置JobDataMap。jobListenerNames属性用于指定job的监听器,类型为String[]。以下是一个例子:
通过jobClass设置了Job实现类,并设置了Job的JobDataMap,指定了applicationContextJobDataKey键,让Job的JobDataMap持有Spring ApplicationContext的引用。以下是MyJobClass的伪实现:
3. JobDetailFactoryBean
由于JobDetailBean继承org.quartz.JobDetail,在Quartz 2.0以后,JobDetail改为接口,所以JobDetailBean不支持Quartz 2.0以上版本。如果使用Quartz2.0以上版本,可以使用JobDetailFactoryBean。支持的属性设置,与JobDetailBean相同。
4. MethodInvokingJobDetailFactoryBean
通常情况下,我们都是实现Job接口定义任务,为了避免这种只包含一行调用代码的Job实现类,Spring提供了MethodInvokingJobDetailFactoryBean,可以将一个Bean的某个方法封装成满足Quartz要求的Job。以下是一个例子:
jobDetail将myJob的work方法封装成一个Job。concurrent属性指定任务的类型,如果为有状态的任务,设置为false即可,默认为true。以下是myJob的伪实现:
work方法可以是static,也可以是非static的。但不能有方法入参。由于MethodInvokingJobDetailFactoryBean实现中通过JobExecutionContext取得Scheduler, 而Scheduler不能被序列化,那么创建的JobDetail也不能被序列化,也就不能持久化到数据库,如果想持久化到数据库,只能通过创建Job实现类的方式。MethodInvokingJobDetailFactoryBean支持quartz1.5以2.0以上版本。
5. SimpleTriggerBean
使用SimpleTriggerBean需要设置jobDetail。SimpleTriggerBean默认使用bean名作为trigger的名称,DEFAULT作为默认组。startDelay属性可以设置延迟触发trigger的时间,单位为毫秒,默认为0。支持以Map方式设置trigger的JobDataMap。以下是一个例子:
在job实现类中,通过以下方式取得jobDataMap:
6. SimpleTriggerFactoryBean
由于SimpleTriggerBean继承了org.quartz.SimpleTrigger,因此不支持Quartz2.0以上版本。如果使用Quartz2.0以上版本,可以使用SimpleTriggerFactoryBean。支持的属性设置,与SimpleTriggerBean相同。
7. CronTriggerBean
CronTriggerBean支持的属性,与SimpleTriggerBean相同。以下是一个例子:
8. CronTriggerFactoryBean
如果使用Quartz2.0以上版本,可以使用CronTriggerFactoryBean。支持的属性设置,与CronTriggerBean相同。
9. SchedulerFactoryBean
Spring提供了SchedulerFactoryBean,可以让Scheduler感知Spring容器的生命周期,在容器启动时,Scheduler自动开始工作,容器关闭前,自动关闭Scheduler。以下是一个例子:
默认情况下,Quartz在类路径下寻找quartz.properties配置文件,可以通过configLocation属性显示指定配置文件的位置。startupDelay属性指定延迟多少时间让容器启动Scheduler,单位为秒。schedulerContextAsMap属性设置了SchedulerContext数据,可以在job中通过JobExecutionContext.getScheduler().getContext().getXxx()方法获取。通过taskExecutor属性设置线程池。支持以Properties方式设置Quartz属性,将覆盖配置文件的值:
为了降低使用Quartz的难度,并能以Spring风格的方式使用Quartz,Spring为Quartz提供了Scheduler, Trigger, JobDetail的FactoryBean类,以及一些工具类,使Quartz能很好的注入容器,并可以结合Spring容器的生命周期,启动和关闭job。
2. JobDetailBean
使用JobDetailBean,需要设置其JobClass属性,指定实现了Job接口的实现类。JobDetailBean默认使用bean名作为job名,DEFAULT作为组名,并可以通过applicationContextJobDataKey键,将ApplicationContext设置到JobDataMap中。JobDetailBean支持以Map方式设置JobDataMap。jobListenerNames属性用于指定job的监听器,类型为String[]。以下是一个例子:
- <bean name="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
- <property name="jobClass" value="com.tboy.example.quartz.MyJobClass" />
- <property name="applicationContextJobDataKey" value="applicationContext"/>
- <property name="jobDataAsMap">
- <map>
- <entry key="container" value="Tomcat"/>
- </map>
- </property>
- </bean>
通过jobClass设置了Job实现类,并设置了Job的JobDataMap,指定了applicationContextJobDataKey键,让Job的JobDataMap持有Spring ApplicationContext的引用。以下是MyJobClass的伪实现:
- public class MyJobClass implements Job{
- @Override
- public void execute(JobExecutionContext context)
- throws JobExecutionException {
- Map dataMap = context.getJobDetail().getJobDataMap();
- String container = (String)dataMap.get("container");
- ApplicationContext applicationContext = (ApplicationContext)dataMap.get("applicationContext");
- //applicationContext.getBean("");
- if(container.equals("Tomcat")){
- //
- }
- //
- }
- }
3. JobDetailFactoryBean
由于JobDetailBean继承org.quartz.JobDetail,在Quartz 2.0以后,JobDetail改为接口,所以JobDetailBean不支持Quartz 2.0以上版本。如果使用Quartz2.0以上版本,可以使用JobDetailFactoryBean。支持的属性设置,与JobDetailBean相同。
4. MethodInvokingJobDetailFactoryBean
通常情况下,我们都是实现Job接口定义任务,为了避免这种只包含一行调用代码的Job实现类,Spring提供了MethodInvokingJobDetailFactoryBean,可以将一个Bean的某个方法封装成满足Quartz要求的Job。以下是一个例子:
- <bean id="myJob" class="com.tboy.example.quartz.MyJob" />
- <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
- <property name="targetObject" ref="myJob" />
- <property name="targetMethod" value="work" />
- <property name="concurrent" value="true"/>
- </bean>
jobDetail将myJob的work方法封装成一个Job。concurrent属性指定任务的类型,如果为有状态的任务,设置为false即可,默认为true。以下是myJob的伪实现:
- public class MyJob {
- public void work(){
- //
- }
- }
work方法可以是static,也可以是非static的。但不能有方法入参。由于MethodInvokingJobDetailFactoryBean实现中通过JobExecutionContext取得Scheduler, 而Scheduler不能被序列化,那么创建的JobDetail也不能被序列化,也就不能持久化到数据库,如果想持久化到数据库,只能通过创建Job实现类的方式。MethodInvokingJobDetailFactoryBean支持quartz1.5以2.0以上版本。
5. SimpleTriggerBean
使用SimpleTriggerBean需要设置jobDetail。SimpleTriggerBean默认使用bean名作为trigger的名称,DEFAULT作为默认组。startDelay属性可以设置延迟触发trigger的时间,单位为毫秒,默认为0。支持以Map方式设置trigger的JobDataMap。以下是一个例子:
- <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
- <property name="jobDetail" ref="jobDetail"/>
- <property name="startDelay" value="1000" />
- <property name="repeatCount" value="5"/>
- <property name="repeatInterval" value="2000"/>
- <property name="jobDataAsMap">
- <map>
- <entry key="count" value="10"/>
- </map>
- </property>
- </bean>
在job实现类中,通过以下方式取得jobDataMap:
- public class MyJob implements Job{
- @Override
- public void execute(JobExecutionContext context)
- throws JobExecutionException {
- Map dataMap = context.getTrigger().getJobDataMap();
- Object count = dataMap.get("count");
- System.out.println(count);
- }
- }
6. SimpleTriggerFactoryBean
由于SimpleTriggerBean继承了org.quartz.SimpleTrigger,因此不支持Quartz2.0以上版本。如果使用Quartz2.0以上版本,可以使用SimpleTriggerFactoryBean。支持的属性设置,与SimpleTriggerBean相同。
7. CronTriggerBean
CronTriggerBean支持的属性,与SimpleTriggerBean相同。以下是一个例子:
- <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
- <property name="jobDetail" ref="jobDetail"/>
- <property name="startDelay" value="1000" />
- <property name="cronExpression">
- <value>0/30 * * * * ?</value>
- </property>
- </bean>
8. CronTriggerFactoryBean
如果使用Quartz2.0以上版本,可以使用CronTriggerFactoryBean。支持的属性设置,与CronTriggerBean相同。
9. SchedulerFactoryBean
Spring提供了SchedulerFactoryBean,可以让Scheduler感知Spring容器的生命周期,在容器启动时,Scheduler自动开始工作,容器关闭前,自动关闭Scheduler。以下是一个例子:
- <bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
- <property name="corePoolSize" value="3" />
- <property name="maxPoolSize" value="5" />
- <property name="queueCapacity" value="10" />
- </bean>
- <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- <ref bean="transferJobCronTrigger" />
- <ref bean="deleteJobCronTrigger" />
- <ref bean="softDeleteJobCronTrigger" />
- </list>
- </property>
- <property name="autoStartup" value="true"/>
- <property name="startupDelay" value="5"/>
- <property name="schedulerContextAsMap">
- <map>
- <entry key="timeout" value="30"/>
- </map>
- </property>
- <property name="taskExecutor" ref="executor" />
- <property name="configLocation" value="classpath:com/tboy.example/quartz/quartz.properties"/>
- </bean>
默认情况下,Quartz在类路径下寻找quartz.properties配置文件,可以通过configLocation属性显示指定配置文件的位置。startupDelay属性指定延迟多少时间让容器启动Scheduler,单位为秒。schedulerContextAsMap属性设置了SchedulerContext数据,可以在job中通过JobExecutionContext.getScheduler().getContext().getXxx()方法获取。通过taskExecutor属性设置线程池。支持以Properties方式设置Quartz属性,将覆盖配置文件的值:
- <property name="quartzProperties">
- <props>
- <prop key="org.quartz.threadPool.class">
- org.quartz.simpl.SimpleThreadPool
- </prop>
- <prop key="org.quartz.threadPool.threadCount">10</prop>
- <prop key="org.quartz.threadPool.threadPriority">5</prop>
- <prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">
- true</prop>
- </props>
- </property>