精华内容
下载资源
问答
  • c# Quartz使用
    千次阅读
    2019-07-12 11:47:00

    记录一下Quartz使用

    Quartz是一款比较好用的定时任务执行工具类,这里就简单说一下用法,至于有何优势或者说需要更深层的挖掘,可能就需要您更多的摸索了。

    winfrom程序实现

    先说一下思路和流程
    
    1. 新建winfrom程序 ,我就命名WindowsFormsApplication1好了
    2. 程序NuGet引入Quartz类库,两种引入方法:第一种,程序包管理控制台输入Install-Package Quartz;第二种在管理解决方案NuGet程序包中搜索Quartz然后安装。
    3. 新建一个文件夹Helper,里面新建两个类Class用来配置Quartz, Quartz和IQuartz,下面会讲解,当然,这两个类名和路径都是没规定的,自己喜欢就好。
    4. 调用Quartz类(第3点新建的Class),完成。

      开始实现……

    第1、2点很简单就不说了,第二点的两个类我就放在一个新建的Helper文件夹下,注意一点就是时间的设定,这个可以根据需求去设置,时间设置在Quartz类的WithCronSchedule中设定,代码实现如下:

    using Quartz;
    using Quartz.Impl;
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace WindowsFormsApplication1.Helper
    {
        public class Quartz
        {
            public static async Task Start()
            {
                try
                {
                    // Grab the Scheduler instance from the Factory
                    NameValueCollection props = new NameValueCollection
                    {
                        { "quartz.serializer.type", "binary" }
                    };
                    StdSchedulerFactory factory = new StdSchedulerFactory(props);
                    IScheduler scheduler = await factory.GetScheduler();
                    await scheduler.Start();
                    IJobDetail tfAlarmJob = JobBuilder.Create<IQuartz>()
                        .WithIdentity("tfAlarmJob", "group1")
                        .Build();
                    ITrigger trigger = TriggerBuilder.Create()
                        .WithIdentity("trigger", "group1")
                     .WithCronSchedule("0 10 20 ? * FRI")//每周五晚上10点10分运行
                         .Build();
                    await scheduler.ScheduleJob(tfAlarmJob, trigger);
                }
                catch (Exception ex)
                {
    
                }
            }
            public interface IJob
            {
            }
        }
    }
    
    
    using Quartz;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace WindowsFormsApplication1.Helper
    {
        [DisallowConcurrentExecution]
        public class IQuartz : IJob
        {
            public Task Execute(IJobExecutionContext context)
            {
                return Task.Run(() =>
                {
                    try
                    {
                    //每周五晚上10点运行Form1.test这个方法
                        Form1.test();
                    }
                    catch (Exception ex)
                    {
    
                    }
                });
            }
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            /// <summary>
            /// winfrom程序加载完成触发
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_Load(object sender, EventArgs e)
            {
                //开始使用Quartz
                Helper.Quartz.Start().GetAwaiter().GetResult();
            }
            public static void test()
            {
    
            }
        }
    }
    
    

    --------------------------------------------------------------------web MVC程序实现---------------------------------------------------------------------------

    ## web MVC程序实现

     其实和上面winfrom说的基本一样,思路和流程如下
    
    1. 新建web MVC程序 ,我就命名WebApplication1
    2. 程序NuGet引入Quartz类库,两种引入方法:第一种,程序包管理控制台输入Install-Package Quartz;第二种在管理解决方案NuGet程序包中搜索Quartz然后安装。
    3. 新建两个类Class用来配置Quartz, Quartz和IQuartz,下面会讲解,当然,这两个类名和路径都是没规定的,自己喜欢就好。
    4. 调用Quartz类(第3点新建的Class),完成。

      开始实现……

    第1、2点很简单就不说了,第二点的两个类我就放在一个新建的Helper文件夹下,注意一点就是时间的设定,这个可以根据需求去设置,时间设置在Quartz类的WithCronSchedule中设定,代码实现如下:

    using Quartz;
    using Quartz.Impl;
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Web;
    
    namespace WebApplication1.Helper
    {
        public class Quartz
        {
            public static async Task Start()
            {
                try
                {
                    // Grab the Scheduler instance from the Factory
                    NameValueCollection props = new NameValueCollection
                    {
                        { "quartz.serializer.type", "binary" }
                    };
                    StdSchedulerFactory factory = new StdSchedulerFactory(props);
                    IScheduler scheduler = await factory.GetScheduler();
                    await scheduler.Start();
                    IJobDetail tfAlarmJob = JobBuilder.Create<IQuartz>()
                        .WithIdentity("tfAlarmJob", "group1")
                        .Build();
                    ITrigger trigger = TriggerBuilder.Create()
                        .WithIdentity("trigger", "group1")
                     .WithCronSchedule("0 10 20 ? * FRI")//每周五晚上10点10分运行
                         .Build();
                    await scheduler.ScheduleJob(tfAlarmJob, trigger);
                }
                catch (Exception ex)
                {
    
                }
            }
            public interface IJob
            {
            }
        }
    }
    
    using Quartz;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Web;
    using WebApplication1.Controllers;
    
    namespace WebApplication1.Helper
    {
        [DisallowConcurrentExecution]
        public class IQuartz : IJob
        {
            public Task Execute(IJobExecutionContext context)
            {
                return Task.Run(() =>
                {
                    try
                    {
                        //设定的时间执行这个方法
                        HomeController.test();
                    }
                    catch (Exception ex)
                    {
    
                    }
                });
            }
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace WebApplication1.Controllers
    {
        public class HomeController : Controller
        {
            public  ActionResult Index()
            {
                //开始使用Quartz
                Helper.Quartz.Start().GetAwaiter().GetResult();
                return View();
            }
    
            public ActionResult About()
            {
                ViewBag.Message = "Your application description page.";
    
                return View();
            }
    
            public ActionResult Contact()
            {
                ViewBag.Message = "Your contact page.";
    
                return View();
            }
            /// <summary>
            /// 测试用的,固定时间调用
            /// </summary>
            public static void test()
            {
               
            }
        }
    }
    
    更多相关内容
  • NULL 博文链接:https://thetopofqingshan.iteye.com/blog/1554390
  • spring整合quartz使用jdbc存储任务,并配置为quartz集群应用
  • idea 使用spring自带的定时器quartz 使用的c3p0 v0.95.2所包含的jar 亲测可用
  • Quartz.NET是一套很好的任务调度框架。下面这篇文章主要给大家介绍了关于.Net Core中使用Quartz.Net的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
  • Quartz使用教程

    万次阅读 2018-06-25 19:26:56
    如果在day-of-week字段里和数字联合使用,它的意思就是 “这个月的最后一个星期几” – 例如: “6L” means “这个月的最后一个星期五”. 当我们用“L”时,不指明一个列表值或者范围是很重要的,不然的话,我们会...
    1.下载

    官网
    下载Quartz框架

    2.解压完查看目录

    目录结构

    3.找到其中的jar包依赖到项目中

    寻找jar包

    依赖jar包

    4.实现任务定时功能

    4.1创建一个任务类

    /**
     * [任务类]
     * @author Edon-Du
     * @date 2018-6-25 
     * @copyright copyright (c) 2018
     */
    public class MyJob implements Job {
    
        @Override
        public void execute(JobExecutionContext arg0) throws JobExecutionException {
            System.out.println("Hello World");
    
        }

    4.2写两个不同定时触发

    /**
     * [说明/描述]
     * @author Edon-Du
     * @date 2018-6-25 
     * @version 1.0
     * @copyright copyright (c) 2018
     */
    public class SchedulerUtil {
        private static Logger _logger = Logger.getLogger(SchedulerUtil.class);// log4j记录日志
        /**
         * [简单任务调度:每次执行间隔为多少毫秒,执行多少次] <br>
         * @author Edon-Du <br>
         * @date 2018-6-25 <br>
         * @param jobName 任务名字
         * @param jobGroupName 任务组名字
         * @param triggerName触发器名字
         * @param triggerGroupName触发器组名字
         * @param jobClass任务类
         * @param intevalTime时间间隔
         * @param count执行几次<br>
         */
        public static void handleSimpleTrigger(String jobName, String jobGroupName,
                String triggerName, String triggerGroupName, Class jobClass,
                int time, int count) {
            // 通过schedulerFactory获取一个调度器
            SchedulerFactory schedulerfactory = new StdSchedulerFactory();
            Scheduler scheduler = null;
            try {
                // 通过schedulerFactory获取一个调度器
                scheduler = schedulerfactory.getScheduler();
                // 创建jobDetail实例,绑定Job实现类
                // 指明job的名称,所在组的名称,以及绑定job类
                JobDetail job = JobBuilder.newJob(jobClass)
                        .withIdentity(jobName, jobGroupName).build();
                // 定义调度触发规则
                 //使用simpleTrigger规则
                 Trigger
                 trigger=TriggerBuilder.newTrigger().withIdentity(triggerName,
                         triggerGroupName)
                 .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(time).withRepeatCount(count))
                 .startNow().build();
                // 把作业和触发器注册到任务调度中
                scheduler.scheduleJob(job, trigger);
                // 启动调度
                scheduler.start();
            } catch (Exception e) {
                _logger.warn("执行"+jobName+"组"+jobName+"任务出现异常E:["+ e.getMessage() + "]");
            }
        }
        /**
         * [复杂任务调度:每天几点几分几秒定时执行任务] <br>
         * @author Edon-Du <br>
         * @date 2018-6-25 <br>
         * @param jobName 任务名字
         * @param jobGroupName 任务组名字
         * @param triggerName 触发器名字
         * @param triggerGroupName 触发器组名字
         * @param jobClass 任务类
         * @param cron 触发规则<br>
         */
        public static void hadleCronTrigger(String jobName, String jobGroupName,
                String triggerName, String triggerGroupName, Class jobClass,String cron) {
            // 通过schedulerFactory获取一个调度器
            SchedulerFactory schedulerfactory = new StdSchedulerFactory();
            Scheduler scheduler = null;
            try {
                // 通过schedulerFactory获取一个调度器
                scheduler = schedulerfactory.getScheduler();
                // 创建jobDetail实例,绑定Job实现类
                // 指明job的名称,所在组的名称,以及绑定job类
                JobDetail job = JobBuilder.newJob(jobClass)
                        .withIdentity(jobName, jobGroupName).build();
                // 定义调度触发规则
                //使用cornTrigger规则  每天18点30分  
                Trigger trigger=TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName)  
                .withSchedule(CronScheduleBuilder.cronSchedule(cron))  
                .startNow().build();    
                // 把作业和触发器注册到任务调度中
                scheduler.scheduleJob(job, trigger);
                // 启动调度
                scheduler.start();
            } catch (Exception e) {
                _logger.warn("执行"+jobName+"组"+jobName+"任务出现异常E:["+ e.getMessage() + "]");
            }
        }
    

    4.3测试

    /**
     * [说明/描述]
     * @author Edon-Du
     * @date 2018-6-25
     * @copyright copyright (c) 2018
     */
    
    public class QuartzSimple {
        public static void main(String[] args) {
            //简单任务调度,每隔多少时间执行一次,执行n次
            SchedulerUtil.handleSimpleTrigger("44033", "3333","44033", "3333", MyJob.class, 1, 8);
            //复杂调度,每天的什么时候执行任务
            SchedulerUtil.hadleCronTrigger("44033", "3333","44033", "3333",MyJob.class,"0 19 19 * * ? *");
        }
    

    4.4完成测试
    完成测试

    常用的一些匹配规则表达式

    字段 允许值 允许的特殊字符
    秒 0-59 , - * /
    分 0-59 , - * /
    小时 0-23 , - * /
    日期 1-31 , - * ? / L W C
    月份 1-12 或者 JAN-DEC , - * /
    星期 1-7 或者 SUN-SAT , - * ? / L C #
    年(可选) 留空, 1970-2099 , - * /
    表达式 意义
    “0 0 12 * * ?” 每天中午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期间的每1分钟触发
    “0 0/5 14 * * ?” 在每天下午2点到下午2:55期间的每5分钟触发
    “0 0/5 14,18 * * ?” 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
    “0 0-5 14 * * ?” 在每天下午2点到下午2:05期间的每1分钟触发
    “0 10,44 14 ? 3 WED” 每年三月的星期三的下午2:10和2:44触发
    “0 15 10 ? * MON-FRI” 周一至周五的上午10:15触发
    “0 15 10 15 * ?” 每月15日上午10:15触发
    “0 15 10 L * ?” 每月最后一日的上午10:15触发
    “0 15 10 ? * 6L” 每月的最后一个星期五上午10:15触发
    “0 15 10 ? * 6L 2002-2005” 2002年至2005年的每月的最后一个星期五上午10:15触发
    “0 15 10 ? * 6#3” 每月的第三个星期五上午10:15触发
    特殊字符 意义
    * 表示所有值;
    ? 表示未说明的值,即不关心它为何值;
    - 表示一个指定的范围;
    , 表示附加一个可能值;
    / 符号前表示开始时间,符号后表示每次递增的值;
    L(“last”) (“last”) “L” 用在day-of-month字段意思是 “这个月最后一天”;用在 day-of-week字段, 它简单意思是 “7” or “SAT”。 如果在day-of-week字段里和数字联合使用,它的意思就是 “这个月的最后一个星期几” – 例如: “6L” means “这个月的最后一个星期五”. 当我们用“L”时,不指明一个列表值或者范围是很重要的,不然的话,我们会得到一些意想不到的结果。
    W(“weekday”) 只能用在day-of-month字段。用来描叙最接近指定天的工作日(周一到周五)。例如:在day-of-month字段用“15W”指“最接近这个月第15天的工作日”,即如果这个月第15天是周六,那么触发器将会在这个月第14天即周五触发;如果这个月第15天是周日,那么触发器将会在这个月第16天即周一触发;如果这个月第15天是周二,那么就在触发器这天触发。注意一点:这个用法只会在当前月计算值,不会越过当前月。“W”字符仅能在day-of-month指明一天,不能是一个范围或列表。也可以用“LW”来指定这个月的最后一个工作日。
    只能用在day-of-week字段。用来指定这个月的第几个周几。例:在day-of-week字段用”6#3”指这个月第3个周五(6指周五,3指第3个)。如果指定的日期不存在,触发器就不会触发。
    C 指和calendar联系后计算过的值。例:在day-of-month 字段用“5C”指在这个月第5天或之后包括calendar的第一天;在day-of-week字段用“1C”指在这周日或之后包括calendar的第一天

    展开全文
  • Quartz使用教程(基础)

    千次阅读 2019-03-22 09:02:50
    1.Quartz介绍 任务调度框架“Quartz”是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统, “任务进度管理器”就是一个在预先确定(被纳入日程)的时间...

    1.Quartz介绍

      任务调度框架“Quartz”是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,

       “任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。

    简单的来说:在某一个有规律的时间点干某件事。并且时间的触发的条件可以非常复杂(比如每月最后一个工作日的17:50),复杂到需要一个专门的框架来干这个事。 Quartz就是来干这样的事,你给它一个触发条件的定义,它负责到了时间点,触发相应的Job起来干活。

    2.Quartz的触发器

     触发器用来告诉调度程序作业什么时候触发。框架提供了5种触发器类型,但两个最常用的SimpleTrigger和CronTrigger。

      五种类型的Trigger(定时器)

       SimpleTrigger,CronTirgger,DateIntervalTrigger,NthIncludedDayTrigger和Calendar类( org.quartz.Calendar)。

       使用场景:

       SimpleTrigger:执行N次,重复N次

       CronTrigger:几秒 几分 几时 哪日 哪月 哪周 哪年,执行

     

    3. 存储方式

    RAMJobStore(内存作业存储类型)和JDBCJobStore(数据库作业存储类型),两种方式对比如下:

      

     优点   缺点
    RAMJobStore要外部数据库,配置容易,运行速度快

    因为调度程序信息是存储在被分配给JVM的内存里面,所以,当应用程序停止运行时,所有调度信息将被丢失。 另外因为存储到JVM内存里面,所以可以存储多少个Job和Trigger将会受到限制

    JDBCJobStor 支持集群,因为所有的任务信息都会保存到数据库中,可以控制事物,还有就是如果应用服务器关闭或者重启,任务信息都不会丢失,并且可以恢复因服务器关闭或者重启而导致执行失败的任务   运行速度的快慢取决与连接数据库的快慢

                                                           

    图解quartz工作流程:      

         å°æé£å_quartz          

                   

                   

             

    quartz相关表达式cron:

    Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:

      (1) Seconds Minutes Hours DayofMonth Month DayofWeek Year

      (2)Seconds Minutes Hours DayofMonth Month DayofWeek

     corn从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份

    各字段的含义:

    字段允许值允许的特殊字符
    秒(Seconds)0~59的整数, - * /    四个字符
    分(Minutes0~59的整数, - * /    四个字符
    小时(Hours0~23的整数, - * /    四个字符
    日期(DayofMonth1~31的整数(但是你需要考虑你月的天数),- * ? / L W C     八个字符
    月份(Month1~12的整数或者 JAN-DEC, - * /    四个字符
    星期(DayofWeek1~7的整数或者 SUN-SAT (1=SUN),- * ? / L W C     八个字符
    年(可选,留空)(Year1970~2099, - * /    四个字符

     

      (1)*:表示匹配该域的任意值。假如在Minutes域使用*, 即表示每分钟都会触发事件。

      (2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。

      (3)-:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次 

      (4)/:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而               25,45等分别触发一次. 

      (5),:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。 

      (6)L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触           发。 

      (7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例              如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在 在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。

      (8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。 

      (9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

    在线生成表达式网址:http://cron.qqe2.com/

    4.代码演示(包含简单调度器以及表达式触发器两类)

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

    具体作业类代码:

    package com.javaxl.quartz01.job;
    
    import org.quartz.*;
    
    /**
     * @author 小李飞刀
     * @site www.javaxl.com
     * @company
     * @create  2019-02-19 11:48
     */
    public class RamJob implements Job {
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            System.out.println("定时任务执行......");
            JobDetail jobDetail = jobExecutionContext.getJobDetail();
            JobDataMap jobDataMap = jobDetail.getJobDataMap();
            System.out.println("定时任务参数:name->"+jobDataMap.get("name")+",job->"
                    +jobDataMap.get("job")+",level->"+jobDataMap.get("level"));
        }
    }

    执行作业类逻辑:

    public static void main(String[] args) throws SchedulerException {
    //        创建调度工厂类实例StdSchedulerFactory
            SchedulerFactory sc=new StdSchedulerFactory();
    //        创建调度器实例Scheduler
            Scheduler scheduler=sc.getScheduler();
    //        创建任务详情JobDetail
            JobDetail jobDetail=newJob(RamJob.class)
                    .withIdentity("detail01","group01")  //组成唯一标识
                    .withDescription("this is a jobDetail")
    //                向具体执行的作业类传值方式一
                    .usingJobData("level","老手")
                    .build();
    
            //向具体执行的作业类传值方式二
            JobDataMap jobDataMap=jobDetail.getJobDataMap();
            jobDataMap.put("name","张三");
            jobDataMap.put("job","司机");
    
            long currentTime = System.currentTimeMillis()+6*1000L;
            Date time = new Date(currentTime);
    
            Trigger trigger= (Trigger) TriggerBuilder.newTrigger()
                    .withIdentity("trigger1","group01")   //组成唯一标识
                    .startAt(time)             //开始时间
                    .withDescription("this is a trigger")
                    简单调度器
    //                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            每隔两秒重复执行3次
    //                        .withIntervalInSeconds(2).withRepeatCount(3))
    
    //                表达式调度器(在线生成定时任务表达式:http://cron.qqe2.com/)
    //                每5秒执行一次作业类逻辑代码
                    .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ? "))
                    .build();
    
    //        注入作业类以及触发器到调度器中
            scheduler.scheduleJob(jobDetail,trigger);
    //        启动调度器
            scheduler.start();
    
        }

    这三个类是quartz的核心类: 

    • Scheduler:调度器。所有的调度都是由它控制。
    • Trigger: 定义触发的条件。例子中,它的类型是SimpleTrigger,每隔1秒中执行一次(什么是SimpleTrigger下面会有详述)。
    • JobDetail & Job: JobDetail 定义的是任务数据,而真正的执行逻辑是在Job中,例子中是HelloQuartz。 为什么设计成JobDetail + Job,不直接使用Job?这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。
    展开全文
  • NULL 博文链接:https://xiuzhi.iteye.com/blog/677695
  • Spring框架中的Quartz使用(详解)

    千次阅读 2017-08-01 20:00:17
    Spring框架中的Quartz使用: 首先简单介绍下Quartz,它是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制,相当于java.util.Timer,但是比Timer多了很多的功能: 1.持久...
    Spring框架中的Quartz使用:
    首先简单介绍下Quartz,它是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制,相当于java.util.Timer,但是比Timer多了很多的功能:
    1.持久性作业,就是保持调度定时的状态;
    2.作业管理,对调度作业进行有效的管理;
    3.类Corn的定时支持,可以用Corn的方式来执行作业;
    4.线程处理模型 Timer是单线程作业的,但是Quartz支持线程缓冲池。


    在Spring中可以很方便的使用Quartz来实现定时任务等功能,我先介绍一下不使用Spring的Quartz实现,主要就是讲解Schedule(任务调度器),Job(作业任务)和Trigger(触发器)三者的关系。具体的体系结构从网上copy过来,讲的比较详细:
    ●Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。


    ●JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail承担了这一角色。


    ●Trigger:是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。当仅需触发一次或者以固定时间间隔周期执行,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:如每早晨9:00执行,周一、周三、周五下午5:00执行等。


    ●Scheduler:代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,两者在Scheduler中拥有各自的组及名称,组及名称是Scheduler查找定位容器中某一对象的依据,Trigger的组及名称必须唯一,JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)。Scheduler定义了多个接口方法,允许外部通过组及名称访问和控制容器中Trigger和JobDetail。


    Scheduler可以将Trigger绑定到某一JobDetail中,这样当Trigger触发时,对应的Job就被执行。一个Job可以对应多个Trigger,但一个Trigger只能对应一个Job。可以通过SchedulerFactory创建一个Scheduler实例。Scheduler拥有一个SchedulerContext,它类似于ServletContext,保存着Scheduler上下文信息,Job和Trigger都可以访问SchedulerContext内的信息。SchedulerContext内部通过一个Map,以键值对的方式维护这些上下文数据,SchedulerContext为保存和获取数据提供了多个put()和getXxx()的方法。可以通过Scheduler# getContext()获取对应的SchedulerContext实例。


    下面简单的helloword代码感受一下Quartz的工作流程:

    [java]  view plain  copy
    1. package quartz;  
    2.   
    3. import java.util.Date;  
    4.   
    5. import org.quartz.Job;  
    6. import org.quartz.JobExecutionContext;  
    7. import org.quartz.JobExecutionException;  
    8.   
    9. public class HelloWord implements Job{  
    10.   
    11.     //实现自己的定时方法  
    12.     public void execute(JobExecutionContext arg0) throws JobExecutionException {  
    13.         System.out.println("hello world " + new Date());  
    14.     }  
    15.       
    16. }  

    [java]  view plain  copy
    1. package quartz;  
    2.   
    3. import java.util.Date;  
    4.   
    5. import org.quartz.JobBuilder;  
    6. import org.quartz.JobDetail;  
    7. import org.quartz.Scheduler;  
    8. import org.quartz.SchedulerException;  
    9. import org.quartz.Trigger;  
    10. import org.quartz.TriggerBuilder;  
    11. import org.quartz.impl.StdSchedulerFactory;  
    12.   
    13.   
    14. public class SimpleExample {  
    15.       
    16.     public static void main(String[] args) throws SchedulerException{  
    17.           
    18.         SimpleExample example=new SimpleExample();  
    19.         example.run();  
    20.     }  
    21.   
    22.     public  void run() throws SchedulerException {  
    23.           
    24.         //获取scheduler实例  
    25.         Scheduler scheduler=StdSchedulerFactory.getDefaultScheduler();  
    26.         scheduler.start();  
    27.           
    28.         //当前时间  
    29.         Date runTime=new Date();  
    30.           
    31.         //定义一个 job 对象并绑定我们写的  HelloWord 类     
    32.         // 真正执行的任务并不是Job接口的实例,而是用反射的方式实例化的一个JobDetail实例   
    33.         JobDetail job=JobBuilder.newJob(HelloWord.class).withIdentity("job1","group1").build();  
    34.           
    35.         // 定义一个触发器,startAt方法定义了任务应当开始的时间 .即下一个整数分钟执行  
    36.         Trigger trigger=TriggerBuilder.newTrigger().withIdentity("trigger1","group1").startAt(runTime).build();  
    37.           
    38.         // 将job和Trigger放入scheduler  
    39.         scheduler.scheduleJob(job, trigger);  
    40.           
    41.         //启动  
    42.         scheduler.start();  
    43.           
    44.         try {  
    45.             Thread.sleep(100);  
    46.         } catch (InterruptedException e) {  
    47.             e.printStackTrace();  
    48.             scheduler.shutdown();  
    49.         }  
    50.           
    51.     }  
    52. }  
    在实际web应用中,我们可用通过使用spring框架来使用Quartz实现定时任务,而且很方便,一共有三种方式:
    (在Srping3.0版本后,使用Quartz需要加入依赖:

    [html]  view plain  copy
    1. <dependency>  
    2. <span style="white-space:pre">    </span><groupId>org.springframework</groupId>  
    3.     <artifactId>spring-context-support</artifactId>  
    4.     <version>3.2.8.RELEASE</version>  
    5. </dependency>  
    否则会报错)
    1.第一种方式,需要继承JobBean,并重写executeInternal(JobExecutionContext context),然后配置spring-quratz.xml文件,里配置三部分:1.任务调用类;2.任务调用方式;3.任务调用工厂:

    [java]  view plain  copy
    1. <pre name="code" class="java">package spring.demo.pojo;  
    2.   
    3. import org.quartz.JobExecutionContext;  
    4. import org.quartz.JobExecutionException;  
    5. import org.springframework.scheduling.quartz.QuartzJobBean;  
    6.   
    7.   
    8. //继承QuartzJobBean,并重写executeInternal方法  
    9. public class QuartzTask extends QuartzJobBean{  
    10.       
    11.     private int timeout;  
    12.     private static int i = 0;  
    13.       
    14.     //调度工厂实例化后,经过timeout时间开始执行调度  
    15.     public void setTimeout(int timeout) {  
    16.         this.timeout = timeout;  
    17.     }  
    18.       
    19.     @Override  
    20.     protected void executeInternal(JobExecutionContext context)  
    21.             throws JobExecutionException {  
    22.         System.out.println("task running..."+ ++i + "进行中...");  
    23.     }  
    24.       
    25. }  


     
    
    [html]  view plain  copy
    1. <!-- 配置任务类 -->  
    2.     <bean id="quartzTask" class="org.springframework.scheduling.quartz.JobDetailBean">  
    3.         <property name="name" value="exampleJob"></property>  
    4.         <property name="quartzClass" value="spring.demo.pojo.QuartzTask"></property>  
    5.         <property name="jobDataAsMap">  
    6.             <map>  
    7.                 <entry key="timeout" value="0" />  
    8.             </map>  
    9.         </property>  
    10.     </bean>  
    [html]  view plain  copy
    1. <!-- 调度触发器方式 -->  
    2. <bean id="cronTriggerBean"  
    3.     class="org.springframework.scheduling.quartz.CronTriggerBean">  
    4.     <property name="jobDetail">  
    5.         <ref bean="quartzTask" />  
    6.     </property>  
    7.     <!-- cron表达式 -->  
    8.     <property name="cronExpression">  
    9.         <value>10,15,20,25,30,35,40,45,50,55 * * * * ?</value>  
    10.     </property>  
    11. </bean>  
    [html]  view plain  copy
    1. <!-- 调度工厂 -->  
    2.     <bean id="SpringJobSchedulerFactoryBean"  
    3.         class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
    4.         <property name="triggers">  
    5.             <list>  
    6.                 <ref bean="cronTriggerBean" />  
    7.             </list>  
    8.         </property>  
    9.     </bean>  

    2.第二种方式,不需要继承基类,这样仍然是pojo,而是在spring-quratz.xml配置文件中,配置包装类,其他两个配置与上述一样:

    [java]  view plain  copy
    1. package spring.demo.pojo;  
    2.   
    3. public class QuartzJob {  
    4.       
    5.     public void work(){  
    6.         System.out.println("work running...");  
    7.     }  
    8. }  

    [java]  view plain  copy
    1. <pre name="code" class="html"><!-- 包装工作类 -->  
    2.     <bean id="quartzJob" class="spring.demo.pojo.QuartzJob"></bean>  
    3.     <bean id="jobTask"  
    4.         class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
    5.         <!-- 需要包装的类,即调度类 -->  
    6.         <property name="targetObject">  
    7.             <ref bean="quartzJob" />  
    8.         </property>  
    9.         <!-- 调用类中的方法 -->  
    10.         <property name="targetMethod">  
    11.             <!-- 具体的方法 -->  
    12.             <value>work</value>  
    13.         </property>  
    14.     </bean>  


     
    
    [html]  view plain  copy
    1. <!-- 调度触发器方式 -->  
    2.     <bean id="cronTriggerBean"  
    3.         class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">  
    4.         <property name="jobDetail">  
    5.             <ref bean="jobTask"/>   
    6.         </property>  
    7.         <!-- cron表达式 -->  
    8.         <property name="cronExpression">  
    9.             <value>10,15,20,25,30,35,40,45,50,55 * * * * ?</value>  
    10.         </property>  
    11.     </bean>  
    [html]  view plain  copy
    1. <!-- 调度工厂 -->  
    2.     <bean id="SpringJobSchedulerFactoryBean"  
    3.         class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
    4.         <property name="triggers">  
    5.             <list>  
    6.                 <ref bean="cronTriggerBean" />  
    7.             </list>  
    8.         </property>  
    9.     </bean>  
    3.第三种方式,通过@Scheduled注解的方式实现,需要修改applicationContext.xml三个部分内容:

    1.xmlns添加:

    [java]  view plain  copy
    1. xmlns:task="http://www.springframework.org/schema/task"  

    2.xsi:schemaLocation添加:

    [java]  view plain  copy
    1. http://www.springframework.org/schema/task  http://www.springframework.org/schema/task/spring-task-3.1.xsd   
    3.applicationContext.xml中添加:

    [java]  view plain  copy
    1. <task:annotation-driven/>  
    最后在我们的定时任务上添加上@Scheduled注解即可,一般都采用cronTrigger方式,即@Scheduled(cron=“相应的定时表达式”)
    [java]  view plain  copy
    1. package spring.demo.service;  
    2.   
    3. import org.springframework.context.support.ClassPathXmlApplicationContext;  
    4. import org.springframework.scheduling.annotation.Scheduled;  
    5. import org.springframework.stereotype.Service;  
    6.   
    7. @Service  
    8. public class QuartzService {  
    9.   
    10.     @Scheduled(cron = "0/2 * * * * *")  
    11.     public void process() {  
    12.         System.out.println("job run...");  
    13.     }  
    14.   
    15.     public static void main(String[] args) throws InterruptedException {  
    16.         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
    17.         while (true) {  
    18.             System.out.println("main running...");  
    19.             Thread.sleep(10000);  
    20.         }  
    21.     }  
    22. }  
    个人建议采用第二种和第三种的方式实现Quartz比较简洁方便,下面顺便在网上查阅关于cron表达式的资料,不过我记得好像有一些工具可以方便生成这些表达式(Visual Cron Editor)目前没有具体的研究过,当然有些表达式也可以百度查阅到:

    Cron表达式包含6个必要组件和一个可选组件,如下表所示:



    特殊字符的含义,见下表:


    Cron表达式举例:
     
    "30 * * * * ?" 每半分钟触发任务
    "30 10 * * * ?" 每小时的10分30秒触发任务
    "30 10 1 * * ?" 每天1点10分30秒触发任务
    "30 10 1 20 * ?" 每月20号1点10分30秒触发任务
    "30 10 1 20 10 ? *" 每年10月20号1点10分30秒触发任务
    "30 10 1 20 10 ? 2011" 2011年10月20号1点10分30秒触发任务
    "30 10 1 ? 10 * 2011" 2011年10月每天1点10分30秒触发任务
    "30 10 1 ? 10 SUN 2011" 2011年10月每周日1点10分30秒触发任务
    "15,30,45 * * * * ?" 每15秒,30秒,45秒时触发任务
    "15-45 * * * * ?" 15到45秒内,每秒都触发任务
    "15/5 * * * * ?" 每分钟的每15秒开始触发,每隔5秒触发一次
    "15-30/5 * * * * ?" 每分钟的15秒到30秒之间开始触发,每隔5秒触发一次
    "0 0/3 * * * ?" 每小时的第0分0秒开始,每三分钟触发一次
    "0 15 10 ? * MON-FRI" 星期一到星期五的10点15分0秒触发任务
    "0 15 10 L * ?" 每个月最后一天的10点15分0秒触发任务
    "0 15 10 LW * ?" 每个月最后一个工作日的10点15分0秒触发任务
    "0 15 10 ? * 5L" 每个月最后一个星期四的10点15分0秒触发任务
    "0 15 10 ? * 5#3" 每个月第三周的星期四的10点15分0秒触发任务
    展开全文
  • Quartz使用-入门使用(java定时任务实现) 注意: 这里使用的是Quartz1.6.5版本(包:quartz-1.6.5.jar)。 代码块测试main函数,例如://测试main函数 //QuartzTest.知识库" target='_bl
  • quartz PostgreSQL 的建表语句中找的如下内容,加到 quartz.properties – In your Quartz properties file, you’ll need to set – org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore....
  • SpringBoot整合quartz2.2.3使用自定义数据源,包括mysql和oracle,使用quartz配合websocket服务器向客户端主动通讯发起通讯。
  • Quartz使用指南

    2011-02-24 13:38:50
    Quartz使用指南 Quartz使用指南 Quartz使用指南
  • 最新springboot+Quartz实现动态定时任务,源代码. 包括controller,service,impl,和配置文件,pom文件,实体类,直接导入springboot项目,配置好数据库就能使用.欢迎下载好评!
  • spring定时任务quartz使用xml配置文件

    千次阅读 2018-05-21 13:22:55
    1. 实现写一个*.xml文件,该文件在spring初始文件中引入该文件。...spring/applicationContext-quartz.xml" /&gt;2. 然后在在定时任务文件中配置3个步骤: &lt;bean id="InsuranceAssociationTas...
  • 今天,给大家来一篇Spring的小插曲,用@Scheduled注解来实现Spring quartz的定时执行任务功能。 导入Spring与Spring quartz相关的jar包,配置applicationContext.xml文件 xmlns 多加下面的内容 xmlns:task=...
  • quartz 的配置里面加上个代理就行了; org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate 数据库的种类太多,互有差异,quartz 在这方面做了一些适配还算良心! ...
  • 主要介绍了Quartz实现JAVA定时任务的动态配置的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • quartz使用指南

    2010-04-01 12:12:54
    quartz使用指南,quartz使用指南,quartz使用指南
  • 定时任务管理之java篇quartz使用

    千次阅读 2014-07-18 20:38:19
    比如夜里低峰时段的备份、统计,或者是每周、每月对数据库表进行整理,这时就需要通过使用定时任务管理器来辅助我们完成这些任务的定时触发。常见的定时任务管理器多分为三类,分别是:  ①操作系统(OS)级别的...
  • 通过数据库配置要执行的类及方法,设定相应时间,定时执行任务
  • spring+quartz使用jar包

    2011-04-14 18:02:11
    spring集成quartz使用需要的jar包下载。
  • spring的quartz使用实例

    2010-07-16 00:12:05
    spring的quartz使用实例,spring的quartz使用实例
  • C# quartz 定时使用教程

    2019-04-05 23:13:02
    强大的调度功能,例如支持丰富多样的调度方法,可以满足各种常规及特殊需求; 灵活的应用方式,例如支持任务和调度的多种组合方式,支持调度数据的多种存储方式; 分布式和集群能力,Terracotta 收购后在原来功能...
  • Quartz 使用任务队列实现顺序调度

    千次阅读 2018-01-09 11:01:44
    Quartz 使用任务队列实现顺序调度把需要并行的任务塞到一个任务队列里面,用一个线程去执行 var:package com.etc.clear.data.common;import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent...
  • quartz.properties #org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore #====================================================================...# Configure ThreadPool (与spring整合后,使用spr...
  • Quartz中文教程学习

    2015-07-08 21:30:30
    Quartz中文教程学习,初学者最实用了
  • 对于任务多且都调用频率不一样的任务,我们都会用到Quartz.Net这个组件; Quartz.NET是一个强大、开源、轻量的作业调度框架,你能够用它来为执行一个作业而创建简单的或复杂的作业调度。它有很...
  • Quartz使用

    万次阅读 2019-01-01 10:33:29
    什么是Quartz Quartz是一个由java编写的开源...Quartz的单独使用 Quartz使用必须掌握下面三个对象 Scheduler 定时器对象 JobDetail 任务对象 Trigger 触发器对象 SimpleTrigger 简单触发器 CornTrigger任务调度...
  • Quartz使用详解

    2011-05-05 07:42:43
    Quartz使用详解 Quartz使用详解 Quartz使用详解 Quartz使用详解 Quartz使用详解 Quartz使用详解

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 96,924
精华内容 38,769
关键字:

quartz使用

友情链接: snphunter.zip