美文网首页
Spring实现定时任务方法

Spring实现定时任务方法

作者: TryCatch菌 | 来源:发表于2018-10-04 10:10 被阅读0次

    从 技术上说实现定时任务常见的方法有三种

    • Java自带的java.util.Timer类
    • 使用Quartz调度器,这种方式需要第三方jar支持
    • Spring3.0以后自带的task定时器

    第一种方式在这里就不多做说明了,因为timer类功能比较单一,在实际项目中运用也比较少

    Quartz

    Quartz的使用方式大致有三种,这三种方式的在这里都会和Spring进行整合所以都会用到applicationContext.xml进行配置

    • 实现org.quartz.StatefulJob或org.quartz.Job接口
    • 继承org.springframework.scheduling.quartz.QuartzJobBean类
    • 普通类+xml配置文件

    1.实现org.quartz.StatefulJob或org.quartz.Job接口
    首先在applicationContext.xml配置定时任务tomcat加载的初始化类,加载时运行init方法

    <!-- 实现定时任务接口启动类 -->
        <bean id="StarJob" class="com.lovo.task.server.impl.StarJob" init-method="init"></bean>
    

    初始化类代码

    package com.lovo.task.server.impl;
    
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class StarJob {
        
        public void init() throws SchedulerException{
            //TestImpl为定时任务的配置实现类
            TestImpl impl=new TestImpl();
            SchedulerFactory factory = new StdSchedulerFactory();  
            Scheduler scheduler = factory.getScheduler(); 
            try {
                //触发作业类及触发器方法
                impl.startJob(scheduler);
            } catch (Throwable e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //启动定时任务
            scheduler.start();
        }
    }
    
    

    作业及调度实现类

    package com.lovo.task.server.impl;
    
    import java.text.ParseException;
    
    import org.quartz.CronTrigger;
    import org.quartz.JobDetail;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.StatefulJob;
    import org.quartz.Trigger;
    import org.quartz.TriggerUtils;
    import org.quartz.impl.StdSchedulerFactory;
    
    import com.lovo.task.server.ITest;
    
    public class TestImpl implements StatefulJob,ITest {
    
        
    
        @Override
        public void execute(JobExecutionContext arg0) throws JobExecutionException {
            // TODO Auto-generated method stub
            test();
        }
        
        @Override
        public void startJob(Scheduler scheduler) throws Throwable {
            //配置作业类
            JobDetail JobDetail=new JobDetail("TestImpl",Scheduler.DEFAULT_GROUP, TestImpl.class);
            //任意每分钟类从0开始55结束,每5秒执行一次
            String rex="0/5 * * * * ?";
            //触发器,配置调度工厂
            CronTrigger trigger=new CronTrigger("testTrigger","testGroup", rex);
            scheduler.scheduleJob(JobDetail, trigger);
            
            //固定每10秒执行一次
    //      Trigger simplerTrigger = TriggerUtils.makeSecondlyTrigger(10);
    //      simplerTrigger.setName("SimpleTrigger");
    //      scheduler.scheduleJob(JobDetail, simplerTrigger);
            
        }
        
        public void test(){
            System.out.println("测试");
        }
        
    }
    
    

    2.继承org.springframework.scheduling.quartz.QuartzJobBean类
    首先在xml中进行配置

        <!-- 配置计时任务 -->
        <!-- 配置作业bean -->
        <bean id="TestTaskImpl" class="org.springframework.scheduling.quartz.JobDetailBean">
            <!-- value为类路径 -->
            <property name="jobClass" value="com.lovo.task.server.impl.TestTaskImpl"></property>
            <!-- 此属性定义方法需注入的属性值,time为工厂调度后多久开始执行 -->
            <property name="jobDataAsMap">
                <map>
                    <entry key="timeout" value="0"></entry>
                </map>
            </property>
        </bean>
        
        <!-- 配置调度触发器 触发器有两种配置方式,一直是固定多少时间循环一次,一种是每天固定几点执行一次,-->
        <!-- 固定频率执行 -->
        <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
            <property name="jobDetail" ref="TestTaskImpl"></property>
            <!-- 实例化后多久开始执行 -->
            <property name="startDelay" value="0"></property>
            <!-- 间隔频率,单位毫秒 -->
            <property name="repeatInterval" value="1000"></property>
        </bean>
        <!-- 固定时间 每天12:00运行一次-->
    <!-- <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
            <property name="jobDetail" ref="TestTaskImpl" />  
            <property name="cronExpression" value="0 0 12 * * ?" />  
        </bean>   -->
        
        <!-- 配置调度工厂 -->
        <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
            <property name="triggers">  
                <list>  
                    <ref bean="simpleTrigger" />  
                </list>  
        </property>  
        </bean> 
    

    作业类代码

    package com.lovo.task.server.impl;
    
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.springframework.scheduling.quartz.QuartzJobBean;
    
    import com.lovo.task.server.TestTask;
    
    public class TestTaskImpl extends QuartzJobBean implements TestTask{
        
        //time为工厂调度后多久开始执行
        private int timeout;
        public static int INDEX;
        
        public void setTime(int timeout) {
            this.timeout = timeout;
        }
    
    
        @Override
        protected void executeInternal(JobExecutionContext arg0)
                throws JobExecutionException {
            // TODO Auto-generated method stub
            testTask();
        }
    
        @Override
        public void testTask() {
            // TODO Auto-generated method stub
            INDEX++;
            System.out.println("执行计时任务第"+INDEX+"次");
            
        }
    
    }
    
    

    3.普通类+xml配置文件
    首先定义个普通JAVA类

    package com.lovo.task.server;
    
    public class TestTask02 {
        
        public void Task(){
            System.out.println("普通类实现定时任务");
        }
    
    }
    
    

    在xml中进行配置

        <!-- 普通类实现定时任务 -->
        <!-- 配置作业类 -->
        <bean id="Task02" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <!-- targetObject指定任务类 -->
            <property name="targetObject">
                <bean class="com.lovo.task.server.TestTask02"></bean>
            </property>
            <!-- targetMethod指定运行的方法 -->
            <property name="targetMethod" value="Task"></property>
            <!-- 不并发调度 -->
            <property name="concurrent" value="false"></property>
        </bean>
        
        <!-- 配置调度触发器 触发器有两种配置方式,一直是固定多少时间循环一次,一种是每天固定几点执行一次 -->
            <bean id="simpleTrigger02" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
            <property name="jobDetail" ref="Task02"></property>
            <!-- 实例化后多久开始执行 -->
            <property name="startDelay" value="0"></property>
            <!-- 间隔频率,单位毫秒 -->
            <property name="repeatInterval" value="1000"></property>
        </bean>
        <!-- 固定时间 每天12:00运行一次-->
    <!-- <bean id="cronTrigger02" class="org.springframework.scheduling.quartz.CronTriggerBean">  
            <property name="jobDetail" ref="Task02" />  
            <property name="cronExpression" value="0 0 12 * * ?" />  
        </bean>   -->
        <!-- 配置调度工厂 -->
        <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
            <property name="triggers">  
                <list>  
                    <ref bean="simpleTrigger02" />  
                </list>  
        </property>  
        </bean> 
    

    Spring-Task

    Spring自带的Task实现定时任务也有两种方式,一种是xml配置的方式,一种是使用注解@Scheduled,不管是那种方式,首先都需要在xml开头声明task

    <?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:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:task="http://www.springframework.org/schema/task" 
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-4.0.xsd
                            http://www.springframework.org/schema/aop
                            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                            http://www.springframework.org/schema/task
                            http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    

    配置定时器开关

    <!-- 配置定时器开关 里面可以配置很多参数,这里只是简单的打开task,并支持@Scheduled -->
            <!-- 配置定时器注解开关 里面可以配置很多参数,这里只是简单的打开task,并支持@Scheduled -->
        <task:scheduler id="Scheduler" pool-size="10"/> 
        <task:annotation-driven scheduler="Scheduler" proxy-target-class="true"/>
    

    基于注解的任务类

    package com.lovo.task.server;
    
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    @Component
    public class Task03 {
        
        @Scheduled(cron="0/3 * * * * ?")
        public void test(){
            System.out.println("task定时任务");
        }
    
    }
    
    

    如果不习惯注解的,追求代码的简洁性,也可以在xml中配置task定时任务

        <!-- 配置作业bean -->
        <bean id="xmlTask" class="com.lovo.task.server.Task04"></bean>
        
        <!-- 配置执行规则  method为作业方法-->
        <task:scheduled-tasks>
            <task:scheduled ref="xmlTask" method="test" cron="0/2 * * * * ?"/>
        </task:scheduled-tasks>
        
        <!-- 配置定时器注解开关 里面可以配置很多参数,这里只是简单的打开task,并支持@Scheduled -->
        <task:scheduler id="Scheduler" pool-size="10"/> 
        <task:annotation-driven scheduler="Scheduler" proxy-target-class="true"/>
    

    定时任务

    package com.lovo.task.server;
    
    public class Task04 {
        
        public void test(){
            System.out.println("xml中配置Task");
        }
    
    }
    
    

    参考来源:
    http://gong1208.iteye.com/blog/1773177
    cronExpression语法
    字段 允许值 允许的特殊字符
    秒 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触发

    相关文章

      网友评论

          本文标题:Spring实现定时任务方法

          本文链接:https://www.haomeiwen.com/subject/iqyvoftx.html