Spring定时器详细配置

UsherOu 2015-03-25

Spring定时器详细配置

本课题参考自《Springinaction》。并非应用系统中发生的所有事情都是由用户的动作引起的。有时候,系统自己也需要发起一些动作。例如,集抄系统每天早上六点把抄表数据传送给营销系统。我们有两种选择:或者是每天由用户手动出发任务,或者让应用系统中按照预定的计划自动执行任务。

在Spring中有两种流行配置:Java的Timer类和OpenSymphony的Quartz来执行调度任务。下面以给商丘做的接口集抄900到中间库的日冻结数据传输为例:

1.JavaTimer调度器

首先定义一个定时器任务,继承java.util.TimerTask类实现run方法

importjava.util.TimerTask;

importxj.service.IJdbc1Service;

importxj.service.IJdbc2Service;

publicclassDayDataTimerTaskextendsTimerTask{

privateIJdbc2Servicejdbc2Service=null;

privateIJdbc1Servicejdbc1Service=null;

publicvoidrun(){

SimpleDateFormatdf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");

System.out.println("日冻结转接任务开始时间:"+df.format(Calendar.getInstance().getTime()));

System.out.println("日冻结转接任务结束时间:"+df.format(Calendar.getInstance().getTime()));

}

//通过set方法获取service服务,如果没有该方法,则为null

publicvoidsetJdbc2Service(IJdbc2Servicejdbc2Service){

this.jdbc2Service=jdbc2Service;

}

publicvoidsetJdbc1Service(IJdbc1Servicejdbc1Service){

this.jdbc1Service=jdbc1Service;

}

}

Run()方法定义了当任务运行时该做什么。jdbc1Service,jdbc2Service通过依赖注入的方式提供给DayDataTimerTask。如果该任务中没有service服务的set方法,则取到的该service服务为null。

其次,在Spring配置文件中声明dayDataTimerTask:

<!--声明定时器任务-->

<beanid="dayDataTimerJob"class="xj.action.DayDataTimerTask">

<propertyname="jdbc1Service">

<refbean="jdbc1Service"/>

</property>

<propertyname="jdbc2Service">

<refbean="jdbc2Service"/>

</property>

</bean>

该声明将DayDataTimerTask放到应用上下文中,并在jdbc1Service、jdbc2Service属性中分别装配jdbc1Service、jdbc2Service。在调度它之前,它不会做任何事情。

<!--调度定时器任务-->

<beanid="scheduledDayDataTimerJob"class="org.springframework.scheduling.timer.ScheduledTimerTask">

<propertyname="timerTask">

<refbean="dayDataTimerJob"/>

</property>

<propertyname="delay">

<value>3000</value>

</property>

<propertyname="period">

<value>864000000</value>

</property>

</bean>

属性timerTask告诉ScheduledTimerTask运行哪个TimerTask。再次,该属性装配了指向scheduledDayDataTimerJob的一个引用,它就是DayDataTimerTask。属性period告诉ScheduledTimerTask以怎样的频度调用TimerTask的run()方法。该属性以毫秒作为单位,它被设置为864000000,指定这个任务应该每24小时运行一次。属性delay允许你指定当任务第一次运行之前应该等待多久。在此指定DayDataTimerTask的第一次运行相对于应用程序的启动时间延迟3秒钟。

<!--启动定时器-->

<beanclass="org.springframework.scheduling.timer.TimerFactoryBean">

<propertyname="scheduledTimerTasks">

<list>

<refbean="scheduledDayDataTimerJob"/>

</list>

</property>

</bean>

Spring的TimerFactoryBean负责启动定时任务。属性scheduledTimerTasks要求一个需要启动的定时器任务的列表。在此只包含一个指向scheduledDayDataTimerJob的引用。

JavaTimer只能指定任务执行的频度,但无法精确指定它何时运行,这是它的一个局限性。要想精确指定任务的启动时间,就需要使用Quartz[kwɔ:ts]调度器。

2.Quartz调度器

Quartz调度器不仅可以定义每隔多少毫秒执行一个工作,还允许你调度一个工作在某个特定的时间或日期执行。

首先创建一个工作,继承QuartzJobBean类实现executeInternal方法

importorg.quartz.JobExecutionContext;

importorg.quartz.JobExecutionException;

importorg.springframework.dao.DataIntegrityViolationException;

importorg.springframework.scheduling.quartz.QuartzJobBean;

importxj.service.IJdbc1Service;

importxj.service.IJdbc2Service;

publicclassDayDataQuartzTaskextendsQuartzJobBean{

privateIJdbc2Servicejdbc2Service=null;

privateIJdbc1Servicejdbc1Service=null;

protectedvoidexecuteInternal(JobExecutionContextcontext)throwsJobExecutionException{

SimpleDateFormatdf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");

System.out.println("日冻结转接任务开始时间:"+df.format(Calendar.getInstance().getTime()));

System.out.println("日冻结转接任务结束时间:"+df.format(Calendar.getInstance().getTime()));

}

//通过set方法获取service服务,如果没有该方法,则为null

publicvoidsetJdbc2Service(IJdbc2Servicejdbc2Service){

this.jdbc2Service=jdbc2Service;

}

publicvoidsetJdbc1Service(IJdbc1Servicejdbc1Service){

this.jdbc1Service=jdbc1Service;

}

}

在Spring配置文件中按照以下方式声明这个工作:

<!--定时启动任务Quartz-->

<!—声明工作-->

<beanid="dayDataJob"class="org.springframework.scheduling.quartz.JobDetailBean">

<propertyname="jobClass">

<value>xj.action.DayDataQuartzTask</value>

</property>

<propertyname="jobDataAsMap">

<map>

<entrykey="jdbc1Service">

<refbean="jdbc1Service"/>

</entry>

<entrykey="jdbc2Service">

<refbean="jdbc2Service"/>

</entry>

</map>

</property>

</bean>

Quartz的org.quartz.Trigger类描述了何时及以怎样的频度运行一个Quartz工作。Spring提供了两个触发器SimpleTriggerBean和CronTriggerBean。SimpleTriggerBean与scheduledTimerTasks类似。指定工作的执行频度,模仿scheduledTimerTasks配置。

<!--调度Simple工作-->

<beanid="simpleDayDataJobTrigger"class="org.springframework.scheduling.quartz.SimpleTriggerBean">

<propertyname="jobDetail">

<refbean="dayDataJob"/>

</property>

<propertyname="startDelay">

<value>1000</value>

</property>

<propertyname="repeatInterval">

<value>86400000</value>

</property>

</bean>

<!—调度cron工作-->

<beanid="dayDataJobTrigger"class="org.springframework.scheduling.quartz.CronTriggerBean">

<propertyname="jobDetail">

<refbean="dayDataJob"/>

</property>

<propertyname="cronExpression">

<value>0302**?</value>

</property>

</bean>

一个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)或一个通配符(如*)。“月份中的日期”和“星期中的日期”这两个元素互斥,应该通过设置一个问号(?)来表明你不想设置的那个字段。

我们在此定义该任务在每天凌晨两点半开始启动。

<!—启动工作-->

<beanclass="org.springframework.scheduling.quartz.SchedulerFactoryBean">

<propertyname="triggers">

<list>

<refbean="simpleDayDataJobTrigger"/>

<refbean="dayDataJobTrigger"/>

</list>

</property>

</bean>

属性triggers接受一组触发器,在此只装配包含simpleDayDataJobTriggerbea和dayDataJobTriggerbean的一个引用列表

2一,首先下载quartz-1.6.0.jar架包,到lib目录下

二,写你自己定时器业务方法

packagecom.lbnet.lzx.timing;

importorg.quartz.JobExecutionContext;

importorg.quartz.JobExecutionException;

importorg.springframework.beans.factory.BeanFactory;

importorg.springframework.context.support.ClassPathXmlApplicationContext;

importorg.springframework.scheduling.quartz.QuartzJobBean;

importcom.lbnet.lzx.service.IOrderService;

publicclassOrderNoRefactextendsQuartzJobBean{

privatestaticBeanFactoryfactory=newClassPathXmlApplicationContext("applicationContext-*.xml");

@Override

protectedvoidexecuteInternal(JobExecutionContextarg0)

throwsJobExecutionException{

//TODOAuto-generatedmethodstub

IOrderServiceorderdao=(IOrderService)factory.getBean("OrderServiceImpl");

System.out.println("订单超时!");

orderdao.updateOrderTimeOver();

}

}

三。在spring文件中进行配置

配置定时任务

<beanid="SchedulerTask3"class="org.springframework.scheduling.quartz.JobDetailBean">

<propertyname="jobClass">

<value>com.lbnet.lzx.timing.OrderNoRefact</value>

</property>

</bean>

配置定时时间

<beanid="SchedulerTaskTrigger3"class="org.springframework.scheduling.quartz.CronTriggerBean">

<propertyname="jobDetail"ref="SchedulerTask3"/>

<propertyname="cronExpression">

<value>00/300/1**?</value>

</property>

</bean>

开启定时任务

<beanclass="org.springframework.scheduling.quartz.SchedulerFactoryBean">

<propertyname="triggers">

<list>

<refbean="SchedulerTaskTrigger3"/>

</list>

</property>

</bean>

四。一些定时参数意义

00/300/1**?代表每天每30分钟运行一次

00/30/1**?代表每天每3分钟运行一次

01123**?代表每天晚上23:11运行一次

五。如果重启报异常

org.apache.commons.collections.SetUtils.orderedSet(Ljava/util/Set;)Ljava/util/Set;

请把commons-collections-2.1.1.jar,checkstytle-all.jar删掉,然后加入commons-collections.jar包就OK了

相关推荐