spring 定时任务
1.Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少,这篇文章将不做详细介绍。
2.使用Quartz,这是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂,稍后会详细介绍。
3. Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多,稍后会介绍。
TimerTask
----------------------------------------------------------------------------------------------------------------------------------
public class TimerListener implements ServletContextListener { public static final long PERIOD_DAY = 24 * 3600 * 1000;// DateUtils.MILLIS_IN_DAY; public static final long PERIOD_WEEK = PERIOD_DAY * 7; public static final long NO_DELAY = 0; private Timer timer; public void contextInitialized(ServletContextEvent event) { timer = new Timer(true); try { timer.schedule(new NewTask(), getDeLay(), 24 * 3600 * 1000); } catch (ParseException e) { try { timer.schedule(new NewTask(), getDeLay(), 24 * 3600 * 1000); } catch (ParseException e1) { e1.printStackTrace(); } e.printStackTrace(); } } public void contextDestroyed(ServletContextEvent event) { timer.cancel(); // 定时器销毁 } long getDeLay() throws ParseException { DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); DateFormat fmt2 = new SimpleDateFormat("yyyy-MM-dd"); long tommorrow = new Date().getTime() + 24 * 3600 * 1000L; String nextDate = fmt2.format(new Date(tommorrow)); nextDate += " 03:00:00"; Date nextD = fmt.parse(nextDate); long delay = nextD.getTime() - new Date().getTime(); return delay; } }
timer.schedule(new NewTask(), getDeLay(), 24 * 3600 * 1000);
void java.util.Timer.schedule(TimerTask task, long delay, long period)
-
schedule
public void schedule(TimerTask task, long delay, long period)
Parameters:task
- task to be scheduled.delay
- delay in milliseconds before task is to be executed.period
- time in milliseconds between successive task executions.
Quartz
----------------------------------------------------------------------------------------------------------------------------------
* 按任务调度的触发时机来分,主要有以下两种:
1.每隔指定时间则触发一次,对应的调度器为org.springframework.scheduling.quartz.SimpleTriggerBean
2.每到指定时间则触发一次,对应的调度器为org.springframework.scheduling.quartz.CronTriggerBean
作业类继承org.springframework.scheduling.quartz.QuartzJobBean类,每到指定时间则触发一次
1.编写作业类
package bean.jobDetailBean; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; public class Job1 extends QuartzJobBean { private int timeout; private static int i = 0; //调度工厂实例化后,经过timeout时间开始执行调度 public void setTimeout(int timeout) { this.timeout = timeout; } /** * 要调度的具体任务 */ @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { System.out.println("继承QuartzJobBean的方式-调度" + ++i + "进行中..."); } }
2.配置作业类
<!-- 作业使用继承QuartzJobBean的方式 --> <bean name="job1" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="bean.jobDetailBean.Job1" /> <property name="jobDataAsMap"> <map> <entry key="timeout" value="0" /> </map> </property> </bean>
3.配置作业调度的触发方式
<!-- 对应于作业继QuartzJobBean类的方式 --> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="job1" /> <!-- "cronExpression"的配置说明 字段 允许值 允许的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小时 0-23 , - * / 日期 1-31 , - * ? / L W C 月份 1-12 或者 JAN-DEC , - * / 星期 1-7 或者 SUN-SAT , - * ? / L C # 年(可选) 留空, 1970-2099 , - * / - 区间 * 通配符 ? 你不想设置那个字段 --> <!-- 每分钟的第0,10,20,30,40,50秒调度一次 --> <property name="cronExpression" value="0,10,20,30,40,50 * * * * ?" /> </bean>
4.配置调度工厂
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger" /> </list> </property> </bean>
5.开启调度
package test; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ScheduleTest { public static void main(String[] args){ BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext*.xml"); } }
6.调度执行的结果
继承QuartzJobBean的方式-调度1进行中...
继承QuartzJobBean的方式-调度2进行中...
继承QuartzJobBean的方式-调度3进行中...
继承QuartzJobBean的方式-调度4进行中...
继承QuartzJobBean的方式-调度5进行中...
继承QuartzJobBean的方式-调度6进行中...
继承QuartzJobBean的方式-调度7进行中...
继承QuartzJobBean的方式-调度8进行中...
继承QuartzJobBean的方式-调度9进行中...
作业类不继承org.springframework.scheduling.quartz.QuartzJobBean类,每隔指定时间则触发一次
1.编写作业类
package bean.jobDetailBean; public class Job2 { private static int i = 0; public void doJob2() { System.out.println("不继承QuartzJobBean方式-调度" + ++i + "进行中..."); } }
2.配置作业类
<bean id="job2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <bean class="bean.jobDetailBean.Job2" /> </property> <property name="targetMethod" value="doJob2" /> <property name="concurrent" value="false" /><!-- 作业不并发调度 --> </bean>
3.配置作业调度的触发方式
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="job2" /> <property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 --> <property name="repeatInterval" value="2000" /><!-- 每2秒调度一次 --> </bean>
4.配置调度工厂
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="simpleTrigger" /> </list> </property> </bean>
5.开启调度
package test; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ScheduleTest { public static void main(String[] args){ BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext*.xml"); } }
6.调度执行的结果
不继承QuartzJobBean方式-调度1进行中...
不继承QuartzJobBean方式-调度2进行中...
不继承QuartzJobBean方式-调度3进行中...
不继承QuartzJobBean方式-调度4进行中...
不继承QuartzJobBean方式-调度5进行中...
不继承QuartzJobBean方式-调度6进行中...
不继承QuartzJobBean方式-调度7进行中...
不继承QuartzJobBean方式-调度8进行中...
不继承QuartzJobBean方式-调度9进行中...
不继承QuartzJobBean方式-调度10进行中...
task
----------------------------------------------------------------------------------------------------------------------------------
<!-- Spring定时器注解开关--> <task:annotation-driven /> <!-- 此处对于定时时间的配置会被注解中的时间配置覆盖,因此,以注解配置为准 --> <task:scheduled-tasks scheduler="myScheduler"> <task:scheduled ref="scheduledTaskManager" method="autoCardCalculate" cron="1/5 * * * * *"/> </task:scheduled-tasks> <task:scheduler id="myScheduler" pool-size="10"/>
@Component("scheduledTaskManager") public class ScheduledTaskManager { /** * cron表达式:* * * * * *(共6位,使用空格隔开,具体如下) * cron表达式:*(秒0-59) *(分钟0-59) *(小时0-23) *(日期1-31) *(月份1-12或是JAN-DEC) *(星期1-7或是SUN-SAT) */ /** * 定时卡点计算。每天凌晨 02:00 执行一次 */ @Scheduled(cron = "0 0 2 * * *") public void autoCardCalculate() { System.out.println("定时卡点计算... " + new Date()); } /** * 心跳更新。启动时执行一次,之后每隔1分钟执行一次 */ @Scheduled(fixedRate = 1000*60*1) public void heartbeat() { System.out.println("心跳更新... " + new Date()); } /** * 卡点持久化。启动时执行一次,之后每隔2分钟执行一次 */ @Scheduled(fixedRate = 1000*60*2) public void persistRecord() { System.out.println("卡点持久化... " + new Date()); } }
捐助开发者
在兴趣的驱动下,写一个免费
的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。 当然,有钱捧个钱场(右上角的爱心标志,支持支付宝和PayPal捐助),没钱捧个人场,谢谢各位。
谢谢您的赞助,我会做的更好!