Spring框架中的定时器quartzquartz如何使用和配置
项目背景
两个不同的平台进行数据交互,使用了中间库。从中间库向自己的数据库中接收数据,代码写完后,每当需要同步的时候都要手动去跑一次代码显然不合理,这个时候就可以使用Spring的quartz-1.6.0.jar实现定时任务。quartz可以用简单的声明式配置即可实现定时任务,并结合了Spring自身的Bean的管理功能,非常方便。
使用方法:
配置:
<beans>
<!--定义时间间隔触发器-->
<bean id="myJobTrigger"class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="myJobDetail"/>
<property name="cronExpression"
<--时间间隔,可以直接填值,这里使用了从配置文件加载的方式-->
value="${cronExpression.thirdToYztJob}" />
</bean>
<!--定时器配置-->
<bean id=" myJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!--指定定时任务类-->
<property name="targetObject">
<bean class="com.mywork.wu.schedule.tasks.MyDoJobClass">
</bean>
</property>
<!--指定定时方法-->
<property name="targetMethod" value="doJob" />
<!--对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,第二个job就开始了。指定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始,第二个被推迟执行(http://nesuk.iteye.com/blog/1582557一个该参数的讨论) -->
<property name="concurrent" value="false" />
</bean>
</beans>
指定类也可以使用(spring的使用,不在赘述):
<beanid="myTimer" class="com.timer.MyTimer"></bean>
<beanid="timeDitail"class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<propertyname="targetObject"ref="myTimer"></property><!-- 指定任务类 -->
<propertyname="targetMethod"value="doit"></property><!-- 指定任务方法 -->
</bean>
<beans>
<!-- 启动定时器,总管理类如果将lazy-init='false'那么容器启动就会执行调度程序 -->
<bean id="startQuertz" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers" ref="jobList" />
<property name="quartzProperties">
<props>
<!--属性详细解释见下文,一般用默认就好,该默认属性在quartz包下面org.quartz.xml目录下名为quartz.properties-->
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">50</prop>
<prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop>
<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
<!-- <propkey="org.quartz.scheduler.skipUpdateCheck">true</prop>-->
<!-- -->
</props>
</property>
<!--<property name="transactionManager" ref="transactionManager"/> -->
<!--配置监听器,主要是监听任务开始、执行、完成三个阶段-->
<property name="globalJobListeners">
<list>
<ref bean="jobListeners"/>
</list>
</property>
</bean>
<bean id="jobListeners" class="com.iflytek.sgy.schedule.listerner.TaskListerner"/>
</beans>
<beans>
<bean id="jobList" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean=" myJobTrigger "/>
</list>
</constructor-arg>
</bean>
</beans>
<!--监听器实现,这里使用了日志记录-->
public class TaskListerner implements JobListener, Serializable {
/** 序列化ID */
private static final long serialVersionUID = 121945776530612500L;
/**
* 日志记录
*/
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public String getName() {
return "erms.task.listerner";
}
/**
* Quartz 启动任务将要进行的事情
*
* @param context Job执行上下文
*
*/
@Override
public void jobToBeExecuted(JobExecutionContextcontext) {
String jobName = context.getJobDetail().getName();
logger.info("任务 [" + jobName + "] 开始");
}
/**
* 在任务执行时执行被拒接
*
* @param context Job执行上下文
*
*/
@Override
public void jobExecutionVetoed(JobExecutionContextcontext) {
String jobName = context.getJobDetail().getName();
logger.info("任务[" + jobName + "] 执行中...");
}
/**
* 任务执行后的事情
*
* @param context
* Job执行上下文
* @param e 异常信息
*
*/
@Override
public void jobWasExecuted(JobExecutionContextcontext, JobExecutionException e) {
String jobName = context.getJobDetail().getName();
logger.info("任务[" + jobName + "] 完成执行用时 [" + context.getJobRunTime() + " ms]");
if (null != e && !e.getMessage().equals("")) {
System.out.println("Exceptionthrown by: " + jobName + "Exception: " + e.getMessage());
}
}
}
quartz的配置属性部分解释:
org.quartz.scheduler.instanceName = QuartzScheduler |
设置调度器的实例名(instanceName) |
org.quartz.scheduler.instanceId = AUTO |
设置调度器的实例 ID (instanceId) |
#Configure ThreadPool |
线程池属性 |
org.quartz.threadPool.threadCount = 5 |
数量 |
org.quartz.threadPool.threadPriority = 5 |
设置工作者线程的优先级 |
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool |
这个值是一个实现了 org.quartz.spi.ThreadPool 接口的类的全限名称。Quartz 自带的线程池实现类是 org.quartz.smpl.SimpleThreadPool,它能够满足大多数用户的需求。 |
#Configure JobStore |
作业存储设置 |
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore |
Job 存储在内存中需通过设置 org.quartz.jobStrore.class 属性为 org.quartz.simpl.RAMJobStore,就像在代码 3.7 所做的那样。假如我们不希望在 JVM 退出之后丢失调度器的状态信息的话,我们可以使用关系型数据库来存储这些信息。这需要另一个作业存储(JobStore) 实现,我们在后面将会讨论到。 |
#Configure Plugins |
插件配置 |
org.quartz.plugin.jobInitializer.class = |
|
org.quartz.plugins.xml.JobInitializationPlugin |
一个声明式扩框架的方法就是通过新加实现了 org.quartz.spi.SchedulerPlugin 接口的类 |
更详细参数配置可以参考 http://kdisk-sina-com.iteye.com/blog/436109
任务类:
public class ThirdToYztJob {
/**
*使用log4j下的Logger记录日志
*想了解log4j的道友可以参考 http://blog.csdn.net/wu020708/article/details/60144901
*/
private Logger logger =LoggerFactory.getLogger(this.getClass());
public void doJob(){
//******
}
希望对路过的道友有参考价值