• spring 09-Spring框架基于QuartZ实现调度任务


    java定时调度任务

    • 定时调度:在无人值守的时候后,系统可在某一时刻执行某些特定功能的机制
    • 定时调度操作分为两种:定时触发、间隔触发
    • java提供两个定时调度处理类:Timer、TimerTask
    • TimerTask主要是定义任务执行,相当于启动一个线程执行某些任务的处理
    • 企业项目开发过程中基本使用两种定时控制的选择
      • quartz组件:企业级定时处理调度组件,需要单独配置
      • Spring Task:轻量级组件,配置简单,可以利用Annotation实现配置处理

    编写任务程序:

    package cn.liang.forget;
    import java.text.SimpleDateFormat;
    import java.util.TimerTask;
    public class TaskDemo01 extends TimerTask {	
    	@Override
    	public void run() {
    		System.out.println("【当前日期时间】" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new java.util.Date()));
    	}
    }
    

    编写间隔触发程序:

    package cn.liang.test;
    import java.util.Timer;
    import cn.liang.forget.TaskDemo01;
    public class TaskTest01 {
    	public static void main(String[] args) {
    		Timer timer = new Timer();
    		//间隔触发
    		timer.schedule(new TaskDemo01(),0,1000);
    	}
    }
    

    输出结果:

    【当前日期时间】2018-12-04 11:36:03.617
    【当前日期时间】2018-12-04 11:36:04.574
    【当前日期时间】2018-12-04 11:36:05.578
    【当前日期时间】2018-12-04 11:36:06.583
    【当前日期时间】2018-12-04 11:36:07.586
    【当前日期时间】2018-12-04 11:36:08.587
    【当前日期时间】2018-12-04 11:36:09.589
    【当前日期时间】2018-12-04 11:36:10.594
    ......
    

    编写延迟触发程序:

    package cn.liang.test;
    import java.util.Timer;
    import cn.liang.forget.TaskDemo01;
    public class TaskTest01 {
    	public static void main(String[] args) {
    		Timer timer = new Timer();
    		//延迟触发
    		timer.schedule(new TaskDemo01(),2000);
    	}
    }
    

    输出结果:

    【当前日期时间】2018-12-04 11:38:58.211
    

    QuartZ实现定时任务

    • QuartZ组件的开发过程有两种实现模式
      • 要求明确的去继承一个父类
      • 利用配置实现方法调度控制,不需要明确继承父类
    • 本次直接基于Spring的配置管理的方式来实现定时调度控制

    导入QuartZ组件开发包,配置Maven的pom.xml文件

    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.0</version>
    </dependency>
    

    继承QuartzJobBean父类实现定时任务

    1、定义任务处理类

    package cn.liang.forget;
    import java.text.SimpleDateFormat;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.springframework.scheduling.quartz.QuartzJobBean;
    public class TaskDemo2 extends QuartzJobBean{
    	@Override
    	protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
    		System.out.println("【当前日期时间】" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new java.util.Date()));
    	}
    }
    

    2、修改applicationContext.xml配置文件

    • 在整个的Spring容器里面注册已经配置好的任务调度类
    <!-- 此处表示将要执行的任务控制类在Spring中进行注册,并且告诉容器,谁来执行具体的任务 -->
    <bean id="taskFactory1" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    	<!-- 当前可以执行任务的程序类,这个类就是QuartzJobBean的子类 -->
    	<property name="jobClass" value="cn.liang.forget.TaskDemo2"/>
    	<!-- 配置一次任务执行时所需要的若干配置信息 -->	
    	<property name="jobDataMap">
    		<map>	<!-- 任务启动之后立即执行 -->
    			<entry key="timeout" value="0"/>
    		</map>
    	</property>
    </bean>
    
    • 配置任务的触发作业的间隔触发
    <!-- 描述的是间隔触发控制 -->
    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
    	<!-- 定义间隔触发的执行程序类 -->
    	<property name="jobDetail" ref="taskFactory1"/>
    	<!-- 定义的是是具体的触发的延迟时间,如果设置为0,表示立刻触发 -->
    	<property name="startDelay" value="0"/>
    	<!-- 间隔触发的频次,间隔时间单位为“毫秒” -->
    	<property name="repeatInterval" value="2000"/>
    </bean>
    
    • 设置任务的触发作业的间隔触发调度器
    <!-- 定义调度工厂类的配置 -->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    	<property name="triggers">
    		<list>
    			<ref bean="simpleTrigger"/> 
    		</list>
    	</property>
    </bean>
    

    启动Spring容器实现间隔触发任务,所有的间隔触发的控制操作都交由Spring管理

    package cn.liang.test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class TaskTest2 {
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    	}
    }
    

    输出结果:

    2018-12-04 14:17:40,050 INFO [org.quartz.impl.StdSchedulerFactory] - Using default implementation for ThreadExecutor
    2018-12-04 14:17:40,076 INFO [org.quartz.core.SchedulerSignalerImpl] - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
    2018-12-04 14:17:40,076 INFO [org.quartz.core.QuartzScheduler] - Quartz Scheduler v.2.3.0 created.
    2018-12-04 14:17:40,084 INFO [org.quartz.simpl.RAMJobStore] - RAMJobStore initialized.
    2018-12-04 14:17:40,085 INFO [org.quartz.core.QuartzScheduler] - Scheduler meta-data: Quartz Scheduler (v2.3.0) 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' with instanceId 'NON_CLUSTERED'
      Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
      NOT STARTED.
      Currently in standby mode.
      Number of jobs executed: 0
      Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
      Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
    
    2018-12-04 14:17:40,086 INFO [org.quartz.impl.StdSchedulerFactory] - Quartz scheduler 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' initialized from an externally provided properties instance.
    2018-12-04 14:17:40,086 INFO [org.quartz.impl.StdSchedulerFactory] - Quartz scheduler version: 2.3.0
    2018-12-04 14:17:40,088 INFO [org.quartz.core.QuartzScheduler] - JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@5bfa9431
    2018-12-04 14:17:40,142 INFO [org.springframework.scheduling.quartz.SchedulerFactoryBean] - Starting Quartz Scheduler now
    2018-12-04 14:17:40,142 INFO [org.quartz.core.QuartzScheduler] - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED started.
    【当前日期时间】2018-12-04 14:17:40.175
    【当前日期时间】2018-12-04 14:17:41.955
    【当前日期时间】2018-12-04 14:17:43.956
    【当前日期时间】2018-12-04 14:17:45.956
    【当前日期时间】2018-12-04 14:17:47.956
    ......
    

    QuartZ使用Cron实现定时触发

    • QuartZ最大的优势是可以结合cron表达式实现定时触发
    • cron服务器可以根据配置文件在约定的时间来执行特定的任务

    cron表达式是一个字符串

    • seconds minutes hours day month week year
    • seconds:表示秒,可以是从0到59之间的任何整数。
    • minutes: 表示分钟,可以是从0到59之间的任何整数。
    • hours:表示小时,可以是从0到23之间的任何整数。
    • day:表示日期,可以是从1到31之间的任何整数。
    • month:表示月份,可以是从1到12之间的任何整数或JAN-DEC范围。
    • week:表示星期几,可以是从1到7之间的任何整数或SUN-SAT范围,这里的1代表星期日。
    • year:表示年,有效范围为1970-2099年

    cron表达式作用域的含义

    • * :表示匹配该域的任意值,假如在minutes域使用*则表示每分钟都会触发事件
    • ? :只能用在day和week两个域上
    • - :表示范围,如果在minutes域使用5-20则表示从5分到20分内,每分钟触发一次
    • / :表示起始时间开始触发,然后每隔固定时间触发一次
    • , :表示列出枚举值
    • L :表示最后,只能用在day和week两个域上,如在week域使用5L则表示最后一个星期四触发
    • W :表示有效工作日(周一到周五),只能出现day域
    • # :表示确认每个月的第几个星期几,只能出现day域,如4#2表示某月的第二个星期三

    cron表达式举例

    • 0 0 2 1 * ? * :表示在每月的1日的凌晨2点调度任务
    • 0 15 10 ? * MON-FRI :表示周一到周五每天上午10:15执行作业
    • 0 15 10 ? * 6L 2018-2030 :表示2018-2030年的每个月的最后一个星期五上午10:15执行作业
    • 0 0 10,14,16 * * ? :表示每天上午10点,下午2点、4点
    • 0 0/30 9-17 * * ? :表示9点到17点工作时间内每半小时
    • 0 0 12 ? * WED :表示每个星期三中午12点
    • 0 0 12 * * ? :表示每天中午12点触发
    • 0 15 10 ? * * :表示每天10:15触发
    • 0 15 10 * * ? :表示每天10:15触发
    • 0 15 10 * * ? 2005 :表示2005年的每天10:15触发
    • 0 * 14 * * ? :表示每天14点到14:59分期间,每1分钟触发
    • 0 0/5 14 * * ? :表示每天14点到14:55分期间,每5分钟触发
    • 0 0/5 14,18 * * ? :表示每天14点到14:55分和18点到18:55分期间,每5分钟触发
    • 0 0-5 14 * * ? :表示每天14点到14:05分期间,每1分钟触发
    • 0 10,44 14 ? 3 WED :表示每年三月的星期三的14:10和14:44触发
    • 0 15 10 ? * MON-FRI :表示周一到周五的10:15触发

    修改applicationContext.xml配置文件,使用间隔控制类进行定时触发处理

    <bean id="taskFactory1" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    	<property name="jobClass" value="cn.liang.forget.TaskDemo2"/>
    	<property name="jobDataMap">
    		<map>
    			<entry key="timeout" value="0"/>
    		</map>
    	</property>
    </bean>
    
    <!-- 使用定时触发处理 -->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    	<!-- 定义间隔触发的执行程序类 -->
    	<property name="jobDetail" ref="taskFactory1"/>
    	<!-- 定义CRON表达式,描述的是每分钟触发一次 -->
    	<property name="cronExpression" value="0 * * * * ?"/>
    </bean>
    
    <!-- 定义调度工厂类的配置 -->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    	<property name="triggers">
    		<list>
    			<ref bean="cronTrigger"/> 
    		</list>
    	</property> 
    </bean>
    

    启动Spring容器实现间隔触发任务,所有的间隔触发的控制操作都交由Spring管理

    package cn.liang.test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class TaskTest2 {
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    	}
    }
    

    输出结果:

    2018-12-04 15:13:07,113 INFO [org.quartz.impl.StdSchedulerFactory] - Using default implementation for ThreadExecutor
    2018-12-04 15:13:07,129 INFO [org.quartz.core.SchedulerSignalerImpl] - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
    2018-12-04 15:13:07,129 INFO [org.quartz.core.QuartzScheduler] - Quartz Scheduler v.2.3.0 created.
    2018-12-04 15:13:07,130 INFO [org.quartz.simpl.RAMJobStore] - RAMJobStore initialized.
    2018-12-04 15:13:07,131 INFO [org.quartz.core.QuartzScheduler] - Scheduler meta-data: Quartz Scheduler (v2.3.0) 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' with instanceId 'NON_CLUSTERED'
      Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
      NOT STARTED.
      Currently in standby mode.
      Number of jobs executed: 0
      Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
      Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
    
    2018-12-04 15:13:07,131 INFO [org.quartz.impl.StdSchedulerFactory] - Quartz scheduler 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' initialized from an externally provided properties instance.
    2018-12-04 15:13:07,131 INFO [org.quartz.impl.StdSchedulerFactory] - Quartz scheduler version: 2.3.0
    2018-12-04 15:13:07,132 INFO [org.quartz.core.QuartzScheduler] - JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@5bfa9431
    2018-12-04 15:13:07,152 INFO [org.springframework.scheduling.quartz.SchedulerFactoryBean] - Starting Quartz Scheduler now
    2018-12-04 15:13:07,153 INFO [org.quartz.core.QuartzScheduler] - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED started.
    【当前日期时间】2018-12-04 15:14:00.021
    【当前日期时间】2018-12-04 15:15:00.004
    

    QuartZ通过配置自动实现调度

    • 由于QuartZ的调用需要继承QuartzJobBean父类,容易导致单继承的局限控制
    • 因此Spring提供了不继承任何类实现的定时处理操作任务

    定义一个处理任务的执行类

    package cn.liang.forget;
    import java.text.SimpleDateFormat;
    public class TaskDemo3{
    	public void task(){
    		System.out.println("【当前日期时间】" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new java.util.Date()));
    	}
    }
    

    修改applicationContext.xml配置文件

    <!-- 配置自定义的任务执行类操作 -->
    <bean id="taskFactory2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    	<!-- 定义要执行任务调度的任务类对象,需要一个具体的对象处理 -->
    	<property name="targetObject">
    		<bean class="cn.liang.forget.TaskDemo3"/>
    	</property>
    	<!-- 定义任务执行的时候所调用的操作方法名称 -->
    	<property name="targetMethod" value="task"/>
    </bean> 
    
    <!-- 使用定时触发处理 -->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    	<!-- 定义间隔触发的执行程序类 -->
    	<property name="jobDetail" ref="taskFactory2"/>
    	<!-- 定义CRON表达式,描述的是每分钟触发一次 -->
    	<property name="cronExpression" value="0 * * * * ?"/>
    </bean>
    
    <!-- 定义调度工厂类的配置 -->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    	<property name="triggers">
    		<list>
    			<ref bean="cronTrigger"/> 
    		</list>
    	</property> 
    </bean>
    

    启动Spring容器实现间隔触发任务,所有的间隔触发的控制操作都交由Spring管理

    package cn.liang.test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class TaskTest2 {
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    	}
    }
    

    输出结果:

    2018-12-04 15:35:59,257 INFO [org.quartz.impl.StdSchedulerFactory] - Using default implementation for ThreadExecutor
    2018-12-04 15:35:59,269 INFO [org.quartz.core.SchedulerSignalerImpl] - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
    2018-12-04 15:35:59,270 INFO [org.quartz.core.QuartzScheduler] - Quartz Scheduler v.2.3.0 created.
    2018-12-04 15:35:59,270 INFO [org.quartz.simpl.RAMJobStore] - RAMJobStore initialized.
    2018-12-04 15:35:59,271 INFO [org.quartz.core.QuartzScheduler] - Scheduler meta-data: Quartz Scheduler (v2.3.0) 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' with instanceId 'NON_CLUSTERED'
      Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
      NOT STARTED.
      Currently in standby mode.
      Number of jobs executed: 0
      Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
      Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
    
    2018-12-04 15:35:59,271 INFO [org.quartz.impl.StdSchedulerFactory] - Quartz scheduler 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' initialized from an externally provided properties instance.
    2018-12-04 15:35:59,271 INFO [org.quartz.impl.StdSchedulerFactory] - Quartz scheduler version: 2.3.0
    2018-12-04 15:35:59,272 INFO [org.quartz.core.QuartzScheduler] - JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@7995092a
    2018-12-04 15:35:59,306 INFO [org.springframework.scheduling.quartz.SchedulerFactoryBean] - Starting Quartz Scheduler now
    2018-12-04 15:35:59,306 INFO [org.quartz.core.QuartzScheduler] - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED started.
    【当前日期时间】2018-12-04 15:36:00.024
    【当前日期时间】2018-12-04 15:37:00.005
    【当前日期时间】2018-12-04 15:38:00.003
    
  • 相关阅读:
    PHP开发环境的搭建
    ios请求服务器数据 ASIHTTPRequest
    Android 调用GPS
    C语言学习规划
    weifenluo与notifyIcon小细节
    初涉Ribbon界面简单编程——图书管理系统——基于MFC+vs2010+win7。
    多线程编程之二——MFC中的多线程开发(转)
    类 StringTokenizer
    表单中Readonly和Disabled的区别
    研究了下Ajax,写了个处理Ajax函数
  • 原文地址:https://www.cnblogs.com/liangjingfu/p/10065146.html
Copyright © 2020-2023  润新知