zoukankan      html  css  js  c++  java
  • spring-spring task原理及使用

    参考:

    https://www.cnblogs.com/qlqwjy/p/9960706.html

    https://blog.csdn.net/debugbugbg/article/details/81091715

    https://blog.csdn.net/weixin_43777983/article/details/99685666

    https://www.cnblogs.com/throwable/p/12616945.html -todo

    SpringTask定时任务的使用

    实现定时任务简单的有四种方式:TimerScheduledThreadPool线程池quartz(常用),还有另一种就是springtask。

      都说springtask上手简单,于是简单的研究一下springtask的使用,并且运用到自己的项目中。其也有两种配置方式,第一种是基于xml配置,第二种是基于注解。

      SprngTask没有专门的包,其核心类位于spring-context包中。所以引入spring的核心包此功能即可使用。

      在实际的项目中,我们经常将job作为action层,在job中注入service去操作底层的dao,或者定时的向其他系统拉取数据,再或者向其他系统推送数据。

    1.基于xml配置的简单的使用

    测试类:(每五秒钟打印一次日志)

    复制代码
    package cn.xm.exam.job;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    @Component
    public class FirstTestJob {
        private static final Logger log = LoggerFactory.getLogger(FirstTestJob.class);
        private static int count;
    
        public void cron() {
            log.info("spring task execute times {}", count++);
        }
    }
    复制代码

    xml配置:(非常类似于quartz的cron表达式和linux定时的cron表达式)

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.springframework.org/schema/beans" 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.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
    
        <context:component-scan base-package="cn.xm.exam.job"></context:component-scan>
    
        <task:scheduled-tasks>
            <task:scheduled ref="firstTestJob" method="cron"
                cron="0/5 * * * * ?" />
        </task:scheduled-tasks>
    
    </beans>
    复制代码

    重点是引入task的schema:

    xmlns:task="http://www.springframework.org/schema/task"
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd

    结果:

    复制代码
    ...
    2018-11-14 22:35:00 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 59 2018-11-14 22:35:05 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 60 2018-11-14 22:35:10 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 61 2018-11-14 22:35:15 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 62 2018-11-14 22:35:20 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 63 2018-11-14 22:35:25 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 64 ...
    复制代码

    2.基于注解的使用

    首先查看注解的源码:

    注解使用必须在xml中开启注解任务,使注解生效:

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.springframework.org/schema/beans" 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.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
    
        <context:component-scan base-package="cn.xm.exam.job"></context:component-scan>
    
        <!-- 开启注解任务 -->
        <task:annotation-driven />
    
    </beans>
    复制代码

    测试类:(每十秒钟打印一次日志)

    复制代码
    package cn.xm.exam.job;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    @Component
    public class FirstAnnotationJob {
        private static final Logger log = LoggerFactory.getLogger(FirstAnnotationJob.class);
        private static int count;
    
        @Scheduled(cron = "0/10 * * * * ?")
        public void cron() {
            log.info("spring anno task execute times {}", count++);
        }
    }
    复制代码

    结果:

    2018-11-14 22:44:40 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 0
    2018-11-14 22:44:50 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 1
    2018-11-14 22:45:00 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 2
    2018-11-14 22:45:10 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 3

    查看@Scheduled的源码:(位于spring-context包内)

    复制代码
    /** <a href="http://www.cpupk.com/decompiler">Eclipse Class Decompiler</a> plugin, Copyright (c) 2017 Chen Chao. */
    package org.springframework.scheduling.annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Scheduled {
    
        /**
         * A cron-like expression, extending the usual UN*X definition to include
         * triggers on the second as well as minute, hour, day of month, month
         * and day of week.  e.g. {@code "0 * * * * MON-FRI"} means once per minute on
         * weekdays (at the top of the minute - the 0th second).
         * @return an expression that can be parsed to a cron schedule
         * @see org.springframework.scheduling.support.CronSequenceGenerator
         */
        String cron() default "";
    
        /**
         * Execute the annotated method with a fixed period between the end
         * of the last invocation and the start of the next.
         * @return the delay in milliseconds
         */
        long fixedDelay() default -1;
    
        /**
         * Execute the annotated method with a fixed period between invocations.
         * @return the period in milliseconds
         */
        long fixedRate() default -1;
    
        /**
         * Number of milliseconds to delay before the first execution of a
         * {@link #fixedRate()} or {@link #fixedDelay()} task.
         * @return the initial delay in milliseconds
         * @since 3.2
         */
        long initialDelay() default 0;
    
    }
    复制代码

    参数解释:(其实源码的注释也写的非常清楚了)

    cron:cron表达式

    fixedDelay:表示从上一个任务完成开始到下一个任务开始的间隔,单位是毫秒

    fixedRate:从上一个任务开始到下一个任务开始的间隔,单位是毫秒。

    initialDelay:任务第一次被调用前的延时,单位毫秒。

    需要注意的是上面的前三个属性只能保留一个,不能同时出现,最后一个延时操作可以与上面三个参数搭配。否则会报异常如下:

    java.lang.IllegalArgumentException: Exactly one of the 'cron', 'fixedDelay', or 'fixedRate' attributes is required.

    接下来我们测试上面的参数: 

    fixedDelay :方法中模拟处理用了2s
    复制代码
    package cn.xm.exam.job;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    @Component
    public class FirstAnnotationJob {
        private static final Logger log = LoggerFactory.getLogger(FirstAnnotationJob.class);
        private static int count;
    
        @Scheduled(fixedDelay = 10000)
        public void cron() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                log.error("InterruptedException ", e);
            }
            log.info("spring anno task execute times {}", count++);
        }
    }
    复制代码

    结果:(实际每两次任务中间相差12s,也就是第一次任务结束10s后开启下次任务)

    2018-11-14 23:02:04 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 1
    2018-11-14 23:02:16 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 2
    2018-11-14 23:02:28 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 3
    2018-11-14 23:02:40 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 4

    fixedRate测试:

    复制代码
    package cn.xm.exam.job;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    @Component
    public class FirstAnnotationJob {
        private static final Logger log = LoggerFactory.getLogger(FirstAnnotationJob.class);
        private static int count;
    
        @Scheduled(fixedRate = 10000)
        public void cron() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                log.error("InterruptedException ", e);
            }
            log.info("spring anno task execute times {}", count++);
        }
    }
    复制代码

    结果:(每两次任务相差10s,也就是本次任务开始之后10s后就开启下次任务,不管中间处理花费多长时间)

    2018-11-14 23:04:47 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 1
    2018-11-14 23:04:57 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 2
    2018-11-14 23:05:07 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 3

    至此完成了springtask的测试,确实比quartz简便的多,使用也简单。

    附一个在线cron表达式生成器:http://cron.qqe2.com/

    SpringTask的入门使用

  • 相关阅读:
    redis 持久化RDB、AOF
    进程、线程、协程
    nginx 常用配置
    Redis详解(一)
    Nginx(一)
    docker compose
    练习1——排序
    8万行的insert数据,Ctrl+c、Ctrl+v后心态崩了(如何在Linux下对MySQL数据库执行sql文件)
    Ubuntu使用+Thinkphp5学习——20(html文件中代码注释掉,但是runtime/temp中的php文件仍然存在)
    Ubuntu使用+Thinkphp5学习——19(新增用户报错strip_tags() expects parameter 1 to be string, array given)
  • 原文地址:https://www.cnblogs.com/xuwc/p/13991477.html
Copyright © 2011-2022 走看看