一 简单的线程方式周期执行
所谓线程式就是规定了和thread类似的timer类每隔一段时间(自己在配置文件中定义的时间)run方法就会被执行一次,所以他是一个单线程类首先需要了解的是他继承自java.util..TimerTask类,执行方法体为其复写的父类中的public void run()方法
package cn.xy.util;
import java.util.TimerTask;
publicclass MyThreadtimer extends TimerTask{
@Override
publicvoid run() {
System.out.println("线程方式定时测试");
}
}
和其他的javabean一样,此类需要在配置文件中注册,另外为了分模块管理applicationContext.xml文件,将专门的定时任务的配置单独放在一个配置文件中,完成后在applicationContext.xml中导入即可applicationContext.xml
Timer.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 周期执行的类注册 -->
<bean id="mythreadtimer" class="cn.xy.util.MyThreadtimer"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
</bean>
<!-- 使用spring的时间调度管理 -->
<!-- 使用此管理器必须导入的spring库为spring misc 库 -->
<bean id="scheduledtimertask"
class="org.springframework.scheduling.timer.ScheduledTimerTask"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<!-- 周期执行的任务可以是list指定的多个线程 -->
<property name="timerTask">
<ref bean="mythreadtimer" />
</property>
<!-- 执行周期 thread中的sleep -->
<property name="period">
<value>10000</value>
</property>
<!-- 在容器启动完成后的延迟执行时间 -->
<property name="delay">
<value>5000</value>
</property>
</bean>
<!-- 类似事物管理一样定时任务也要委托给spring的定时工厂进行管理 -->
<bean id="timerFactory"
class="org.springframework.scheduling.timer.TimerFactoryBean"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledtimertask" />
</list>
</property>
</bean>
</beans>
下面是测试类
package cn.xy.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestApp {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// ApplicationContext context2 = new ClassPathXmlApplicationContext("applicationContext.xml");
}
// 只要加载配置文件就可以了,
}
二 特定的时间执行特定的任务,这也是大多数系统需要的重要特性,比如指定在没天的上午10点或每个礼拜的礼拜几执行特定得任务,它与上面那种方式不同的是他隐藏了线程信息,不过只要是定时就是线称,它反复的执行的操作为getdata操作并与配置文件中的比较如果相同则进行相应的操作
此时定时任务类继承
org.quartz.JobExecutionContext
类进行任务编写操作
package cn.xy.util;
import java.util.Date;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
publicclass Mytimerservice extends QuartzJobBean {
@Override
protectedvoid executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
System.out.println(new Date().toString()+"定时任务测试");
}
}
配置定时任务的xml文件servicetimer.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="jobdetailbean"
class="org.springframework.scheduling.quartz.JobDetailBean"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="jobClass">
<value>cn.xy.util.Mytimerservice</value>
</property>
<!-- 注入任务类所需要的bean
<property name="jobDataAsMap">
<map>
<entry key="topimgop">
<ref bean="topimgop"/>
</entry>
</map>
</property>
-->
</bean>
<!-- 定时器注册 -->
<bean id="servicetrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<!-- 任务的详细信息 -->
<property name="jobDetail">
<ref bean="jobdetailbean" />
</property>
<!-- 定时执行的时间 上午11点07分-->
<property name="cronExpression">
<value>0 20 11 * * ?</value>
</property>
</bean>
<!-- 定时任务工厂注册 -->
<bean id="schedulerFactory"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="triggers">
<list>
<ref bean="servicetrigger" />
</list>
</property>
</bean>
</beans>
Quartz设计者做了一个设计选择来从调度分离开作业。Quartz中的触发器用来告诉调度程序作业什么时候触发。框架提供了一把触发器类型,但两个最常用的是SimpleTrigger和CronTrigger。SimpleTrigger为需要简单打火调度而设计。典型地,如果你需要在给定的时间和重复次数或者两次打火之间等待的秒数打火一个作业,那么SimpleTrigger适合你。另一方面,如果你有许多复杂的作业调度,那么或许需要CronTrigger。
CronTrigger是基于Calendar-like调度的。当你需要在除星期六和星期天外的每天上午10点半执行作业时,那么应该使用CronTrigger。正如它的名字所暗示的那样,CronTrigger是基于Unix克隆表达式的。
作为一个例子,下面的Quartz克隆表达式将在星期一到星期五的每天上午10点15分执行一个作业。
0 15 10 * MON-FRI
下面的表达式
0 15 10 * 6L 2002-2005
将在2002年到2005年的每个月的最后一个星期五上午10点15分执行作业。
你不可能用SimpleTrigger来做这些事情。你可以用两者之中的任何一个,但哪个跟合适则取决于你的调度需要。
更多详细介绍参考此处:
关于cronExpression的介绍:
字段 | | 允许值 | | 允许的特殊字符 |
---|
秒 | | 0-59 | | , - * / |
分 | | 0-59 | | , - * / |
小时 | | 0-23 | | , - * / |
日期 | | 1-31 | | , - * / L W C |
月份 | | 1-12 或者 JAN-DEC | | , - * / |
星期 | | 1-7 或者 SUN-SAT | | , - * / L C # |
年(可选) | | 留空, 1970-2099 | | , - * / |
如上面的表达式所示:
“*”字符被用来指定所有的值。如:”*“在分钟的字段域里表示“每分钟”。
“-”字符被用来指定一个范围。如:“10-12”在小时域意味着“10点、11点、12点”。
“,”字符被用来指定另外的值。如:“MON,WED,FRI”在星期域里表示”星期一、星期三、星期五”.
“?”字符只在日期域和星期域中使用。它被用来指定“非明确的值”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。看下面的例子你就会明白。
“L”字符指定在月或者星期中的某天(最后一天)。即“Last ”的缩写。但是在星期和月中“L”表示不同的意思,如:在月子段中“L”指月份的最后一天-1月31日,2月28日,如果在星期字段中则简单的表示为“7”或者“SAT”。如果在星期字段中在某个value值得后面,则表示“某月的最后一个星期value”,如“6L”表示某月的最后一个星期五。
“W”字符只能用在月份字段中,该字段指定了离指定日期最近的那个星期日。
“#”字符只能用在星期字段,该字段指定了第几个星期value在某月中
表达式 | | 意义 |
---|
"0 0 12 * * ?" | | 每天中午12点触发 |
"0 15 10 ? * *" | | 每天上午10:15触发 |
"0 15 10 * * ?" | | 每天上午10:15触发 |
"0 15 10 * * ? *" | | 每天上午10:15触发 |
"0 15 10 * * ? 2005" | | 2005年的每天上午10:15 触发 |
"0 * 14 * * ?" | | 在每天下午2点到下午2:59期间的每1分钟触发 |
"0 0/5 14 * * ?" | | 在每天下午2点到下午2:55期间的每5分钟触发 |
"0 0/5 14,18 * * ?" | | 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 |
"0 0-5 14 * * ?" | | 在每天下午2点到下午2:05期间的每1分钟触发 |
"0 10,44 14 ? 3 WED" | | 每年三月的星期三的下午2:10和2:44触发 |
"0 15 10 ? * MON-FRI" | | 周一至周五的上午10:15触发 |
"0 15 10 15 * ?" | | 每月15日上午10:15触发 |
"0 15 10 L * ?" | | 每月最后一日的上午10:15触发 |
"0 15 10 ? * 6L" | | 每月的最后一个星期五上午10:15触发 |
"0 15 10 ? * 6L 2002-2005" | | 2002年至2005年的每月的最后一个星期五上午10:15触发 |
"0 15 10 ? * 6#3" | | 每月的第三个星期五上午10:15触发 |
每天早上6点
0 6 * * *
每两个小时
0 */2 * * *
晚上11点到早上8点之间每两个小时,早上八点
0 23-7/2,8 * * *
每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
0 11 4 * 1-3
1月1日早上4点
0 4 1 1 *
由于Quartz 2.x修改了部分API,所以需要修改一下Quartz的配置,同事需要将Spring升级到3.1以上。大体来说很简单,如下:
1)升级Spring的jar包
2)升级Quartz的jar包
3)修改配置
将CronTriggerBean修改为CronTriggerFactoryBean
将JobDetailBean修改为JobDetailFactoryBean