日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【原创】Quartz代码详解

發(fā)布時間:2024/9/5 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【原创】Quartz代码详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

閱讀目錄

  • 簡單介紹
  • 章節(jié)1:Quartz簡單實例
  • 章節(jié)2:Job、JobDetail、JobBuilder
  • 章節(jié)3:Trigger、TriggerBuilder
  • 章節(jié)4:Scheduler
  • 章節(jié)5:JobListener、SchedulerListener、TriggerListener
  • 章節(jié)6:Cron表達式
  • 章節(jié)7:程序示例
  • 章節(jié)8:參考鏈接

簡單介紹

在實際編程中,我們經常會遇到定時任務,或是隔一段時間執(zhí)行指定任務,例如:1. 在每月的30號9:00統(tǒng)計人員出勤情況;2. 每隔10分鐘執(zhí)行一次入庫操作;上面的例子中,需要執(zhí)行的操作就是Job(作業(yè)),而在指定時間或者間隔固定時間去觸發(fā)這個Job的就是Trigger(觸發(fā)器),而把二者聯(lián)系在一起的就是Scheduler(調度器);
Quartz主要要理解三個方面:
  • Scheduler:調度器,將Job和Trigger關聯(lián)起來;
  • Job ? ? ? ? ?:需要執(zhí)行的作業(yè);
  • Trigger ? ?:觸發(fā)器,指定執(zhí)行的時間,主要包括兩種方式:
  • <1>指定時間:如每月15號9:00,或者每天的12:00等等;<2>間隔時間:如每隔10分鐘執(zhí)行一次,每隔2h執(zhí)行一次等等;
    回到頂部

    一、Quartz簡單實例

    下面給出一個簡單的示例:SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();?? Scheduler sched = schedFact.getScheduler();?? sched.start();?? // define the job and tie it to our HelloJob class? JobDetail job = newJob(HelloJob.class)????? .withIdentity("myJob", "group1")????? .build();?? // Trigger the job to run now, and then every 40 seconds? trigger = newTrigger()????? .withIdentity("myTrigger", "group1")????? .startNow()????? .withSchedule(simpleSchedule()????????? .withIntervalInSeconds(40)????????? .repeatForever())????? .build();?? // Tell quartz to schedule the job using our trigger? sched.scheduleJob(job, trigger);下面的截圖是Java源碼給出的示例:

    我們在使用Quartz時,一般的操作步驟為:步驟1:自定義Job類(如:MyJob),實現(xiàn)Job接口;步驟2:使用JobBuilder生成JobDetail;步驟3:定義Trigger類,一般使用TriggerBuilder生成;步驟4:定義Scheduler類,使用Scheduler .scheduleJob(job, trigger)將job和trigger進行關聯(lián);步驟5Scheduler.start();步驟6:當需要關閉Scheduler時,使用Scheduler.shutdown();下面將具體進行講解。
    回到頂部

    二、Job、JobDetail、JobBuilder

    官方定義:
  • Job - an interface to be implemented by components that you wish to have executed by the scheduler.
  • JobDetail - used to define instances of Jobs.
  • JobBuilder - used to define/build JobDetail instances, which define instances of Jobs.

  • Job

    Job是一個接口類,下面是它的源碼:
    如果要實現(xiàn)自己的作業(yè)(任務),最簡單的方式就是實現(xiàn)該接口,并實現(xiàn)接口中的execute()方法,當觸發(fā)該作業(yè)時,就是執(zhí)行execute()方法;public class HelloJob implements Job {public HelloJob() {}public void execute(JobExecutionContext context)throws JobExecutionException{System.err.println("Hello! HelloJob is executing.");}}

    JobDetail?

    JobDetail :用于定義Job的實例,一般該類都是通過JobBuilder生成;
    JobBuilder:用于定義或創(chuàng)建JobDetail實例,使用了建造者模式;JobDetail job = newJob(HelloJob.class).withIdentity("myJob", "group1") // name "myJob", group "group1".build();//帶參數(shù)JobDetail job = JobBuilder.newJob(clazz).withIdentity(new JobKey(jobName, groupName)).usingJobData(new JobDataMap(params)).build();從上面的接口類中我們可以知道,只要有了JobDetail的實現(xiàn)類,我們就可以獲取到:
  • key;
  • JobClass;
  • JobDataMap;等
  • 那我們在自定義的Job中怎么才能獲取到JobDetail相關信息呢?
    由上面可知,當自定義的作業(yè)被觸發(fā)時,我們可以通過JobExecutionContext獲取到JobDetail,進而獲取JobDataMap、JobKey、JobClass等等信息;

    JobBuilder

    這里JobBuilder使用了建造者模式,下面對其源碼進行解析;對于建造者模式,這里不進行詳述,首先看下它的字段:

    JobKey:作業(yè)的唯一標識,由name和group組成,如下:

    jobClass:指定上述我們講的自定義的Job(如:HelloJob );



    JobDataMap:可以通過這個屬性給自定義的Job(如:HelloJob)傳遞參數(shù);
    因為使用了建造者模式,所以實際創(chuàng)建的對象為:JobDetailImpl
    JobDetailImpl類實現(xiàn)了JobDeteil接口,如下:
    下圖是類的層級結構圖:


    回到頂部

    三、Trigger、TriggerBuilder

    官方定義:Trigger - a component that defines the schedule upon which a given Job will be executed.TriggerBuilder - used to define/build Trigger instances.
    下面是觸發(fā)器層次結構,常用的有SimpleTrigger、CronTrigger等;

    SimpleTrigger



    主要屬性:

    CronTrigger

    使用CronTrigger可以進行很強大的控制,關于Cron表達式,下面的章節(jié)會介紹;
    主要的參數(shù):


    TriggerBuilder

    首先看下實現(xiàn)的例子:使用的也是建造者模式(建造者模式可自行搜索);
    TriggerBuilder的屬性如下:


    通過withIdentity()方法設定trigger唯一標識:

    通過forJob()方法將Trigger和指定的Job綁定前面我們已經知道:
    • 在使用JobBuilder創(chuàng)建JobDetail時,通過方法withIdentity()指定了JobDetail的JobKey;
    • 這里通過TriggerBuilder的forJob()同樣指定了JobKey;
    ==>只要上面兩個JobKey設置的相同,則JobDetail和Trigger便綁定在一起了;后面只需要使用Scheduler.scheduleJob(job,trigger)進行調度即可;

    通過方法withSchedule設置調度器:
    從上面可以看出,這個方法傳遞進去的實際上是一個調度器Scheduler的Builder,真正的調度器Scheduler還是需要通過ScheduleBuilder去創(chuàng)建,這里使用的還是建造者模式,從下面的層次可以看出,已經實現(xiàn)了4種ScheduleBuilder,這里以SimplesCheduleBuilder進行分析,其他類似
    下面我們看看SimplesCheduleBuilder的源碼實現(xiàn);


    上面是build方法,可以看出,真正創(chuàng)建的是:SimpleTriggerImpl類,這個類在上面已經介紹過,它是Trigger的一個實現(xiàn)類;



    我們接著看TriggerBuilder的build方法:


    回到頂部

    四、Scheduler

    官方定義:Scheduler - the main API for interacting with the scheduler.
    與調度程序交互的主要API。
    具體實現(xiàn)類:
    主要的方法:
  • Scheduler? scheduler = StdSchedulerFactory.getDefaultScheduler();
  • scheduler.schedeleJob(Job,trigger)
  • scheduler.start();
  • scheduler.shutdown();
  • 說明:只有在scheduler.start();之后,trigger以及Job才能有效運行;shutdown用于關閉;
    schedeleJob方法介紹
    // Tell quartz to schedule the job using our trigger? sched.scheduleJob(job, trigger);官方介紹如下:
    現(xiàn)在以StdScheduler作為示例進行介紹:
    start()方法介紹
    使用start()方法來激活Trigger,執(zhí)行定時任務;



    回到頂部

    五、JobListener、SchedulerListener、TriggerListener




    對監(jiān)聽進行注冊:
    ? ? ??回到頂部

    六、Cron表達式

    語法格式:
    示例:

    • *?("all values") - used to select all values within a field. For example, "" in the minute field means *"every minute".

    • ??("no specific value") - useful when you need to specify something in one of the two fields in which the character is allowed, but not the other. For example, if I want my trigger to fire on a particular day of the month (say, the 10th), but don't care what day of the week that happens to be, I would put "10" in the day-of-month field, and "?" in the day-of-week field. See the examples below for clarification.

    • -?- used to specify ranges. For example, "10-12" in the hour field means?"the hours 10, 11 and 12".

    • ,?- used to specify additional values. For example, "MON,WED,FRI" in the day-of-week field means?"the days Monday, Wednesday, and Friday".

    • /?- used to specify increments. For example, "0/15" in the seconds field means?"the seconds 0, 15, 30, and 45". And "5/15" in the seconds field means?"the seconds 5, 20, 35, and 50". You can also specify '/' after the '' character - in this case '' is equivalent to having '0' before the '/'. '1/3' in the day-of-month field means?"fire every 3 days starting on the first day of the month".

    • L?("last") - has different meaning in each of the two fields in which it is allowed. For example, the value "L" in the day-of-month field means?"the last day of the month"?- day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself, it simply means "7" or "SAT". But if used in the day-of-week field after another value, it means?"the last xxx day of the month"?- for example "6L" means?"the last friday of the month". You can also specify an offset from the last day of the month, such as "L-3" which would mean the third-to-last day of the calendar month.?When using the 'L' option, it is important not to specify lists, or ranges of values, as you'll get confusing/unexpected results.

    • W?("weekday") - used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify "15W" as the value for the day-of-month field, the meaning is:?"the nearest weekday to the 15th of the month". So if the 15th is a Saturday, the trigger will fire on Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th. However if you specify "1W" as the value for day-of-month, and the 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not 'jump' over the boundary of a month's days. The 'W' character can only be specified when the day-of-month is a single day, not a range or list of days.

    The 'L' and 'W' characters can also be combined in the day-of-month field to yield 'LW', which translates to *"last weekday of the month"*.
    • #?- used to specify "the nth" XXX day of the month. For example, the value of "6#3" in the day-of-week field means"the third Friday of the month"?(day 6 = Friday and "#3" = the 3rd one in the month). Other examples: "2#1" = the first Monday of the month and "4#5" = the fifth Wednesday of the month. Note that if you specify "#5" and there is not 5 of the given day-of-week in the month, then no firing will occur that month.
    ? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ???? ?? ?? ?回到頂部

    七、程序示例


    AbstractSchedule類:抽象基類



  • package com.sssppp.TimerSchedule.quartz.schedule;
  • import java.util.Date;
  • import java.util.Map;
  • import java.util.Properties;
  • import org.quartz.CronScheduleBuilder;
  • import org.quartz.CronTrigger;
  • import org.quartz.JobBuilder;
  • import org.quartz.JobDataMap;
  • import org.quartz.JobDetail;
  • import org.quartz.JobKey;
  • import org.quartz.Scheduler;
  • import org.quartz.SchedulerException;
  • import org.quartz.TriggerBuilder;
  • import org.quartz.impl.StdSchedulerFactory;
  • import com.sssppp.TimerSchedule.quartz.listeners.MyJobListener;
  • import com.sssppp.TimerSchedule.quartz.listeners.MySchedulerListener;
  • import com.sssppp.TimerSchedule.quartz.listeners.MyTriggerListener;
  • public abstract class AbstractSchedule {
  • public Scheduler scheduler = null;
  • private static final String JOB_GROUPNAME = "MY_JOB_GROUP";
  • private static final String TRIGGER_GROUPNAME = "MY_TRIGGER_GROUP";
  • /**
  • * 初始化Scheduler,并添加Listeners
  • */
  • public AbstractSchedule() {
  • try {
  • if (scheduler == null) {
  • System.out.println("Begin init scheduler...");
  • try {
  • Properties props = new Properties();
  • props.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS,
  • "org.quartz.simpl.SimpleThreadPool");
  • props.put("org.quartz.threadPool.threadCount", "100");// 同時100個線程運行
  • props.put("org.quartz.jobStore.misfireThreshold", "180000");// trigger過期30分鐘內還有效
  • StdSchedulerFactory factory = new StdSchedulerFactory();
  • factory.initialize(props);
  • scheduler = factory.getScheduler();
  • } catch (SchedulerException e) {
  • e.printStackTrace();
  • }
  • scheduler.getListenerManager().addJobListener(new MyJobListener());
  • scheduler.getListenerManager().addSchedulerListener(
  • new MySchedulerListener());
  • scheduler.getListenerManager().addTriggerListener(
  • new MyTriggerListener());
  • }
  • } catch (Exception e) {
  • System.err.println("Init scheduler failed, error message :" + e);
  • }
  • }
  • public abstract Scheduler handleJob(String jobName, String triggerName,
  • String cronStr);
  • @SuppressWarnings({ "unchecked", "rawtypes" })
  • public void scheduleJob(String jobName, String triggerName, String express,
  • Class clazz) {
  • JobDetail job = null;
  • CronTrigger trigger = null;
  • try {
  • job = JobBuilder.newJob(clazz).withIdentity(jobName, JOB_GROUPNAME)
  • .build();
  • trigger = TriggerBuilder.newTrigger()
  • .withIdentity(triggerName, TRIGGER_GROUPNAME)
  • .forJob(jobName, JOB_GROUPNAME)
  • .withSchedule(CronScheduleBuilder.cronSchedule(express))
  • .build();
  • } catch (Exception e) {
  • System.err.println("scheduler ParseException!" + e);
  • }
  • Date date = null;
  • try {
  • date = scheduler.scheduleJob(job, trigger);
  • } catch (SchedulerException e) {
  • System.err.println("scheduler SchedulerException!" + e);
  • }
  • System.out.println(job.getKey().toString()
  • + " has been scheduled to run at: " + date
  • + " and repeat based on expression: "
  • + trigger.getCronExpression());
  • }
  • /**
  • * 創(chuàng)建JobTrigger,并使用schedulerjobTrigger進行關聯(lián)
  • *
  • * @param jobName
  • * @param triggerName
  • * @param express
  • * :cronStr表達式
  • * @param clazz
  • * jobclass
  • * @param params
  • * Job使用的參數(shù)
  • */
  • @SuppressWarnings({ "unchecked", "rawtypes" })
  • public void scheduleJobWithParams(String jobName, String triggerName,
  • String express, Class clazz, Map<String, Object> params) {
  • JobDetail job = null;
  • CronTrigger trigger = null;
  • try {
  • job = JobBuilder.newJob(clazz)
  • .withIdentity(new JobKey(jobName, JOB_GROUPNAME))
  • .usingJobData(new JobDataMap(params)).build();
  • trigger = TriggerBuilder.newTrigger()
  • .withIdentity(triggerName, TRIGGER_GROUPNAME)
  • .forJob(jobName, JOB_GROUPNAME)
  • .withSchedule(CronScheduleBuilder.cronSchedule(express))
  • .build();
  • } catch (Exception e) {
  • System.err.println("scheduler ParseException!" + e);
  • }
  • Date date = null;
  • try {
  • date = scheduler.scheduleJob(job, trigger);
  • } catch (SchedulerException e) {
  • System.err.println("scheduler SchedulerException!" + e);
  • }
  • System.out.println(job.getKey().toString()
  • + " has been scheduled to run at: " + date
  • + " and repeat based on expression: "
  • + trigger.getCronExpression());
  • }
  • /**
  • * Starts the Scheduler's threads that fire Triggers
  • */
  • public void startJob() {
  • try {
  • this.scheduler.start();
  • } catch (SchedulerException e) {
  • System.err.println("trigger job error!" + e);
  • }
  • }
  • public boolean stopJob(String jobName) {
  • boolean b = false;
  • JobKey jobkey = new JobKey(jobName, JOB_GROUPNAME);
  • try {
  • if (this.scheduler.checkExists(jobkey)) {
  • b = this.scheduler.deleteJob(jobkey);
  • System.out.println("Stop Job[" + jobName + "] success.");
  • }
  • } catch (SchedulerException e) {
  • System.err.println("Stop job fail.");
  • e.printStackTrace();
  • }
  • return b;
  • }
  • public void shutdownScheduler() {
  • try {
  • this.scheduler.shutdown(true);
  • System.out.println("Shutdown scheduler success.");
  • } catch (SchedulerException e) {
  • System.err.println("Shutdown Scheduler fail.");
  • e.printStackTrace();
  • }
  • }
  • }

  • MyJobSchedule.java
  • package com.sssppp.TimerSchedule.quartz.schedule;
  • import java.util.HashMap;
  • import java.util.Map;
  • import org.quartz.Scheduler;
  • import com.sssppp.TimerSchedule.quartz.Jobs.MyJob;
  • public class MyJobSchedule extends AbstractSchedule {
  • private static MyJobSchedule myJobSchedule = new MyJobSchedule();
  • private MyJobSchedule() {
  • }
  • public static MyJobSchedule getInstance() {
  • return myJobSchedule;
  • }
  • @Override
  • public Scheduler handleJob(String jobName, String triggerName,
  • String cronStr) {
  • Map<String, Object> params = new HashMap<String, Object>();
  • params.put(MyJob.JOB_PARAM_KEY, "This is myJob param");
  • scheduleJobWithParams(jobName, triggerName, cronStr, MyJob.class, params);
  • startJob();
  • return this.scheduler;
  • }
  • }

  • MyJob.java

  • package com.sssppp.TimerSchedule.quartz.Jobs;
  • import java.util.Date;
  • import org.quartz.Job;
  • import org.quartz.JobExecutionContext;
  • import org.quartz.JobExecutionException;
  • import com.ibm.icu.text.SimpleDateFormat;
  • public class MyJob implements Job {
  • public final static String JOB_PARAM_KEY = "jobParam";
  • @Override
  • public void execute(JobExecutionContext jobexecutioncontext)
  • throws JobExecutionException {
  • SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  • // 獲取傳遞給Job的參數(shù)
  • String param = (String) jobexecutioncontext.getJobDetail()
  • .getJobDataMap().get(JOB_PARAM_KEY);
  • System.out.println("Now exec MyJob,param【" + param + "】, time:"
  • + sdf.format(new Date()));
  • }
  • }

  • QuartzManager.java
  • package com.sssppp.TimerSchedule.quartz;
  • import com.sssppp.TimerSchedule.quartz.schedule.MyJobSchedule;
  • public class QuartzManager {
  • private static final QuartzManager quartzManager = new QuartzManager();
  • private static final String MY_JOB_NAME = "MY_JOB_NAME";
  • private static final String MY_TRIGGER_NAME = "MY_TRIGGER_NAME";
  • private static final String MY_JOB_CRONSTR = "0/5 * * * * ?";
  • private QuartzManager() {
  • }
  • public static QuartzManager getInstance() {
  • return quartzManager;
  • }
  • public void startMyJob() {
  • MyJobSchedule.getInstance().handleJob(MY_JOB_NAME, MY_TRIGGER_NAME,
  • MY_JOB_CRONSTR);
  • }
  • public void stopMyJobAndShutdownScheduler() {
  • MyJobSchedule.getInstance().stopJob(MY_JOB_NAME);
  • MyJobSchedule.getInstance().shutdownScheduler();
  • }
  • }





  • TestCase.java
  • package com.sssppp.TimerSchedule.quartz;
  • public class TestCase {
  • @SuppressWarnings("static-access")
  • public static void main(String[] args) throws InterruptedException {
  • QuartzManager.getInstance().startMyJob();
  • Thread.currentThread().sleep(12 * 1000);
  • QuartzManager.getInstance().stopMyJobAndShutdownScheduler();
  • }
  • }























  • 回到頂部

    八、參考鏈接

    http://www.cnblogs.com/ssslinppp?http://www.quartz-scheduler.org/
    http://www.quartz-scheduler.org/documentation/quartz-2.1.x/tutorials/crontrigger?



    來自為知筆記(Wiz)

    附件列表

    • 1.png
    • 1_2.png
    • 1_3.png
    • 2.png
    • 3.png
    • a2.png

    ?

    轉載于:https://www.cnblogs.com/ssslinppp/p/5055524.html

    總結

    以上是生活随笔為你收集整理的【原创】Quartz代码详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。