[置顶] 史上最全最详细的Spring定时任务的讲解以及实例
2017-09-29 13:46
701 查看
一、最原始的定时任务
1.采用线程方式
二、采用jdk中的Timer类
三、Spring自身集成的Task任务
(1)配置文件方式
(2)注解方式
首先要开启注解驱动
任务类
四、Spring结合Quartz实现精确定时任务
(1)最标准的写法
(2)复杂的Quartz调用
最后开启测试类
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("timer/spring-quartz-task.xml");
AbstractApplicationContext context = new ClassPathXmlApplicationContext("timer/simple-quartz-task.xml");
}
1.采用线程方式
public static void runTask(){ final long timeInterval = 1000; Runnable runnable = new Runnable() { public void run() { while (true){ System.out.println("hello"); try { Thread.sleep(timeInterval); }catch (InterruptedException e){ e.printStackTrace(); } } } }; Thread thread = new Thread(runnable); thread.start(); }
二、采用jdk中的Timer类
package com.flx.timer; import com.flx.timer.task.SimpleTask; import com.flx.timer.task.SimpleTaskLiving; import com.flx.util.BaseFunction; import com.flx.util.date.CalendarUtils; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * Created by Fenglixiong on 2017/9/25. */ public class TimerHome { private static Timer timer = new Timer(); public static void main(String[] args) { TaskOne(10); TaskTwo(CalendarUtils.addSeconds(new Date(),10)); TaskThree(CalendarUtils.addSeconds(new Date(),10)); TaskFour(); TaskFive(CalendarUtils.addSeconds(new Date(),10)); TaskSix(); TimerTaskPool(); TimerTask01(); TimerTask02(); } /** * 指定延迟时间执行定时任务 * @param time */ public static void TaskOne(int time){ BaseFunction.console("准备执行任务TaskOne..."); Timer timer = new Timer(); timer.schedule(new SimpleTask(),time*1000); } /** * 在指定时间执行任务 * @param date */ public static void TaskTwo(Date date){ BaseFunction.console("准备执行任务TaskTwo..."); CalendarUtils.sayTime(new Date()); Timer timer = new Timer(); timer.schedule(new SimpleTask(),date); } /** * 在指定时间执行然后以指定时间间隔执行任务 * @param date */ public static void TaskThree(Date date){ BaseFunction.console("准备执行任务TaskThree..."); CalendarUtils.sayTime(new Date()); Timer timer = new Timer(); timer.schedule(new SimpleTaskLiving("TaskThree"),date,3000); } /** * 在指定时间延迟之后执行然后以指定时间间隔执行任务 * */ public static void TaskFour(){ BaseFunction.console("准备执行任务TaskFour..."); CalendarUtils.sayTime(new Date()); Timer timer = new Timer(); timer.schedule(new SimpleTaskLiving("TaskFour"),5000,3000); } /** * 在指定时间延迟之后执行然后以指定时间间隔执行任务 * */ public static void TaskFive(Date firstTime){ BaseFunction.console("准备执行任务TaskFive..."); CalendarUtils.sayTime(new Date()); Timer timer = new Timer("TaskFive"); timer.scheduleAtFixedRate(new SimpleTaskLiving(),firstTime,3000); } /** * 在指定时间延迟之后执行然后以指定时间间隔执行任务 * */ public static void TaskSix(){ BaseFunction.console("准备执行任务TaskSix..."); CalendarUtils.sayTime(new Date()); Timer timer = new Timer(); timer.scheduleAtFixedRate(new SimpleTaskLiving("TaskSix"),20000,3000); } /** * TimerTask01(); * TimerTask02(); * 同时执行这两个task * 1.如果是两个Timer的话相当于两个线程互相不会影响 * 2.如果是一个Timer的话计划执行两个定时任务的话 * 其中一个延迟或者阻塞会影响另一个任务的执行 */ public static void TimerTask01(){ CalendarUtils.sayTime(new Date()); timer.schedule(new TimerTask() { public void run() { System.out.println("start:TimerTask01"); try { BaseFunction.console("运行:--->TimerTask01"); Thread.sleep(15000); //线程休眠3000 BaseFunction.console("休眠后--->TimerTask01"); CalendarUtils.sayTime(new Date()); // throw new RuntimeException(); } catch (InterruptedException e) { e.printStackTrace(); } } }, 1000); } public static void TimerTask02(){ CalendarUtils.sayTime(new Date()); timer.schedule(new TimerTask() { public void run() { System.out.println("运行:TimerTask02"); CalendarUtils.sayTime(new Date()); // throw new RuntimeException("..."); } }, 5000); } /** * ScheduledExecutorService是从Java SE5的java.util.concurrent里, * 做为并发工具类被引进的,这是最理想的定时任务实现方式。 */ public static void TimerTaskPool(){ Runnable runnable = new Runnable() { public void run() { // task to run goes here System.out.println("Hello !!"); } }; ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.scheduleAtFixedRate(runnable,10,1, TimeUnit.SECONDS); } } /** schedule(TimerTask task, Date time):安排在指定的时间执行指定的任务。 schedule(TimerTask task, Date firstTime, long period) :安排指定的任务在指定的时间开始进行重复的固定延迟执行。 schedule(TimerTask task, long delay) :安排在指定延迟后执行指定的任务。 schedule(TimerTask task, long delay, long period) :安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。 同时也重载了scheduleAtFixedRate方法,scheduleAtFixedRate方法与schedule相同,只不过他们的侧重点不同,区别后面分析。 scheduleAtFixedRate(TimerTask task, Date firstTime, long period):安排指定的任务在指定的时间开始进行重复的固定速率执行。 scheduleAtFixedRate(TimerTask task, long delay, long period):安排指定的任务在指定的延迟后开始进行重复的固定速率执行。 */ /** * TimerTask TimerTask类是一个抽象类,由Timer 安排为一次执行或重复执行的任务。它有一个抽象方法run()方法, 该方法用于执行相应计时器任务要执行的操作。因此每一个具体的任务类都必须继承TimerTask,然后重写run()方法。 另外它还有两个非抽象的方法: boolean cancel():取消此计时器任务。 long scheduledExecutionTime():返回此任务最近实际执行的安排执行时间。 */
三、Spring自身集成的Task任务
(1)配置文件方式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"> <!--此任务写到注解执行了--> <!--<task:scheduled-tasks>--> <!--<task:scheduled ref="simpleTaskJob" method="jobOne" cron="0/2 * * * * ?"/>--> <!--</task:scheduled-tasks>--> <!--新闻抓取--> <task:scheduled-tasks> <task:scheduled ref="simpleTaskService" method="sayHello" cron="0/2 * * * * ?" fixed-delay="1000"/> </task:scheduled-tasks> <!--债券抓取--> <task:scheduled-tasks> <task:scheduled ref="simpleTaskService" method="sayGood" cron="0/5 * * * * ?" /> </task:scheduled-tasks> <!--上证E互动--> <task:scheduled-tasks> <task:scheduled ref="simpleTaskService" method="sayLove" cron="0/10 * * * * ?" /> </task:scheduled-tasks> <!--公告--> <task:scheduled-tasks> <task:scheduled ref="simpleTaskService" method="sayNo" cron="0/15 * * * * ?" /> </task:scheduled-tasks> <!--港交所股票持有数抓取--> <task:scheduled-tasks> <task:scheduled ref="simpleTaskService" method="sayYes" cron="0/20 * * * * ?" /> </task:scheduled-tasks> </beans> <!-- 字段 允许值 允许的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小时 0-23 , - * / 日期 1-31 , - * ? / L W C 月份 1-12 或者 JAN-DEC , - * / 星期 1-7 或者 SUN-SAT , - * ? / L C # 年(可选) 留空, 1970-2099 , - * / - 区间 * 通配符 ? 你不想设置那个字段 下面只例出几个式子 CRON表达式 含义 "0 0 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分每分钟一次触发 "0 0/5 14 * * ?" 每天从下午2点开始到2:55分结束每5分钟一次触发 "0 0/5 14,18 * * ?" 每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发 "0 0-5 14 * * ?" 每天14:00至14:05每分钟一次触发 "0 10,44 14 ? 3 WED" 三月的每周三的14:10和14:44触发 "0 15 10 ? * MON-FRI" 每个周一、周二、周三、周四、周五的10:15触发 -->
(2)注解方式
首先要开启注解驱动
<task:annotation-driven scheduler="poolScheduler" mode="proxy"/> <task:scheduler id="poolScheduler" pool-size="10"/>
任务类
@Service public class SimpleTaskJob { private int count = 0; /** * ApplicationContext.xml中配置了注解驱动之后完美执行任务 * 下面解除注释就可以执行 */ @Scheduled(cron = "0/2 * * * * ?") public void jobOne() { System.out.println("jobOne任务中....."+(++count)); } }
四、Spring结合Quartz实现精确定时任务
(1)最标准的写法
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!--1.增加线程池,用于任务注册--> <bean id="poolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="10"/> <property name="maxPoolSize" value="20"/> <property name="queueCapacity" value="500"/> </bean> <!--2.定义业务逻辑处理类--> <bean id="simpleTask" class="com.flx.quartz.schedule.SimpleTask"/> <!--3.增加调度业务逻辑--> <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="simpleTask"/> <property name="targetMethod" value="doTask"/> </bean> <!--4.增加调度触发器--> <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <property name="jobDetail" ref="jobDetail"/> <property name="startDelay" value="3000"/> <property name="repeatInterval" value="2000"/> </bean> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="jobDetail"/> <property name="cronExpression" value="0/3 * * * * ?"/> </bean> <!--5.增加调度--> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="simpleTrigger"/> <ref bean="cronTrigger"/> </list> </property> <property name="taskExecutor" ref="poolTaskExecutor"/> </bean> </beans>
(2)复杂的Quartz调用
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"> <!--定时器数据,可选--> <bean id="message" class="com.flx.app.entity.Message"> <property name="status" value="100"/> <property name="message" value="very good"/> </bean> <bean id="methodTask" class="com.flx.quartz.schedule.MethodTask"/> <!--Job任务类start--> <!-- For times when you just need to invoke a method on a specific object --> <bean id="simpleTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="methodTask"/> <property name="targetMethod" value="sayHello"/> </bean> <bean id="firstComplexJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.flx.quartz.schedule.FirstComplexJobDetail"/> <property name="jobDataMap"> <map> <entry key="message" value-ref="message"/> </map> </property> <!--即使trigger不关联也不会被删除--> <property name="durability" value="true"/> </bean> <bean id="secondComplexJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.flx.quartz.schedule.SecondComplexJobDetail"/> <property name="durability" value="true"/> </bean> <!--如果你需要更高级的设置,需要给作业传递数据,想更加灵活的话就使用这种方式。--> <bean id="simpleJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.flx.quartz.schedule.SimpleQuartzJob"/> <property name="jobDataMap"> <map> <entry key="me ab2c ssage" value-ref="message"/> </map> </property> <!--如果一个任务不是durable,那么当没有Trigger关联它的时候,它就会被自动删除。--> <property name="durability" value="true"/> <property name="description" value="简单的作业实现"/> </bean> <!--Job任务类end--> <!--A简单触发器--> <!--配置 Quartz 调度时要使用到的触发器--> <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <property name="jobDetail" ref="simpleTask"/> <property name="startDelay" value="3000"/> <property name="repeatInterval" value="2000"/> <property name="repeatCount" value="4"/> <!--<property name="startTime" value=""/>--> </bean> <!--B计划触发器--> <!--这种类型更加灵活,允许你针对特定实例选择计划方案以及将来要执行的频率。--> <bean id="firstCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="firstComplexJobDetail"/> <property name="cronExpression" value="0/5 * * ? * *"/> </bean> <bean id="secondCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="secondComplexJobDetail"/> <property name="cronExpression" value="0/10 * * ? * *"/> </bean> <!--将任务和计划全部整合在以前--> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="simpleTrigger"/> <ref bean="firstCronTrigger"/> <ref bean="secondCronTrigger"/> </list> </property> </bean> </beans>
最后开启测试类
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("timer/spring-quartz-task.xml");
AbstractApplicationContext context = new ClassPathXmlApplicationContext("timer/simple-quartz-task.xml");
}
相关文章推荐
- spring3 之后自带的定时任务以及实例
- Spring 定时任务的配置说明以及实例
- Spring中@Transactional事务回滚(含实例详细讲解,附源码)
- [置顶] spring整合quartz实现动态定时任务的前台网页配置与管理
- Android MP3播放器实例--------MusicActivity类以及MusicService类详细讲解
- Spring任务调度之Spring-Task--应用实例:实现邮件(带附件)定时发送功能
- Spring的连接数据库以及JDBC模板(实例讲解)
- Spring+EhCache缓存实例(详细讲解+源码下载)
- Java实现Web应用中的定时任务(实例讲解)
- 解决Spring定时计划任务重复执行两次或多次(实例被构造两次)问题的方法
- [置顶] 超详细Spring入门讲解
- RabbitMQ与java、Spring结合实例详细讲解
- Spring Boot 定时任务实例分析
- Spring中@Transactional事务回滚(含实例详细讲解,附源码)
- Spring中@Transactional事务回滚(含实例详细讲解,附源码)
- RabbitMQ与java、Spring结合实例详细讲解
- Spring定时任务实例
- SpringBoot整合Quartz定时任务 的简单实例
- Spring的任务调度服务实例讲解
- Spring中@Transactional事务回滚(含实例详细讲解,附源码)