欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Quartz之Job與JobDetail深入解析

 更新時間:2017年06月15日 09:33:29   投稿:jingxian  
下面小編就為大家?guī)硪黄猀uartz之Job與JobDetail深入解析。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

Quartz可以用來做什么?

Quartz是一個任務(wù)調(diào)度框架。比如你遇到這樣的問題

想每月25號,信用卡自動還款

想每年4月1日自己給當(dāng)年暗戀女神發(fā)一封匿名賀卡

想每隔1小時,備份一下自己的愛情動作片 學(xué)習(xí)筆記到云盤

這些問題總結(jié)起來就是:在某一個有規(guī)律的時間點干某件事。并且時間的觸發(fā)的條件可以非常復(fù)雜(比如每月最后一個工作日的17:50),復(fù)雜到需要一個專門的框架來干這個事。 Quartz就是來干這樣的事,你給它一個觸發(fā)條件的定義,它負(fù)責(zé)到了時間點,觸發(fā)相應(yīng)的Job起來干活。

廢話不多說,代碼杠杠的。。。

public static void main(String[] args) {
   try { //創(chuàng)建scheduler
  Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

  //定義一個Trigger
  Trigger trigger =TriggerBuilder.newTrigger().withIdentity("trigger1", "group1") //定義name/group
    .startNow()//一旦加入scheduler,立即生效
    .withSchedule(SimpleScheduleBuilder.simpleSchedule() //使用SimpleTrigger
      .withIntervalInSeconds(1) //每隔一秒執(zhí)行一次
      .repeatForever()) //一直執(zhí)行
    .build();
  //定義一個JobDetail
  JobDetail job =JobBuilder.newJob(HelloQuartz.class) //定義Job類為HelloQuartz類,這是真正的執(zhí)行邏輯所在
    .withIdentity("job1", "group1") //定義name/group
    .usingJobData("name", "quartz") //定義屬性
    .build();
  //加入這個調(diào)度
  scheduler.scheduleJob(job, trigger);
  //啟動之
  scheduler.start();
  //運(yùn)行一段時間后關(guān)閉
   Thread.sleep(10000);
   scheduler.shutdown(true);
  } catch (Exception e) {
  e.printStackTrace();
}

}

HelloQuartz類

public class HelloQuartz implements Job {
  public void execute(JobExecutionContext context) throws JobExecutionException {
    JobDetail detail = context.getJobDetail();
    String name = detail.getJobDataMap().getString("name");
    System.out.println("say hello to " + name + " at " + new Date());
  }
}

jar包:

這個例子很好的覆蓋了Quartz最重要的3個基本要素:

Scheduler:調(diào)度器。所有的調(diào)度都是由它控制。

Trigger: 定義觸發(fā)的條件。例子中,它的類型是SimpleTrigger,每隔1秒中執(zhí)行一次(什么是SimpleTrigger下面會有詳述)。

JobDetail & Job: JobDetail 定義的是任務(wù)數(shù)據(jù),而真正的執(zhí)行邏輯是在Job中,例子中是HelloQuartz。 為什么設(shè)計成JobDetail + Job,不直接使用Job?這是因為任務(wù)是有可能并發(fā)執(zhí)行,如果Scheduler直接使用Job,就會存在對同一個Job實例并發(fā)訪問的問題。而JobDetail & Job 方式,sheduler每次執(zhí)行,都會根據(jù)JobDetail創(chuàng)建一個新的Job實例,這樣就可以規(guī)避并發(fā)訪問的問題。

Scheduler

Scheduler就是Quartz的大腦,所有任務(wù)都是由它來設(shè)施。

Schduelr包含一個兩個重要組件: JobStore和ThreadPool。

JobStore是會來存儲運(yùn)行時信息的,包括Trigger,Schduler,JobDetail,業(yè)務(wù)鎖等。它有多種實現(xiàn)RAMJob(內(nèi)存實現(xiàn)),JobStoreTX(JDBC,事務(wù)由Quartz管理),JobStoreCMT(JDBC,使用容器事務(wù)),ClusteredJobStore(集群實現(xiàn))、TerracottaJobStore(什么是Terractta)。

ThreadPool就是線程池,Quartz有自己的線程池實現(xiàn)。所有任務(wù)的都會由線程池執(zhí)行。

SchedulerFactory

SchdulerFactory,顧名思義就是來用創(chuàng)建Schduler了,有兩個實現(xiàn):DirectSchedulerFactory和 StdSchdulerFactory。前者可以用來在代碼里定制你自己的Schduler參數(shù)。后者是直接讀取classpath下的quartz.properties(不存在就都使用默認(rèn)值)配置來實例化Schduler。通常來講,我們使用StdSchdulerFactory也就足夠了。

SchdulerFactory本身是支持創(chuàng)建RMI stub的,可以用來管理遠(yuǎn)程的Scheduler,功能與本地一樣,可以遠(yuǎn)程提交個Job什么的。

1.job

實現(xiàn)類JobDetail

JobDetail job = JobBuilder.newJob(RemindJob.class)
      .withIdentity("job1", "group1").build();//創(chuàng)建一個任務(wù)

  
   /**
   * 創(chuàng)建觸發(fā)器
   * 第一種方式 不太好
   */
  SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "myTriggerGroup").
  withSchedule(SimpleScheduleBuilder.simpleSchedule().
      withIntervalInSeconds(3).
      repeatForever()).
      startAt(new Date(System.currentTimeMillis()+1000)).build();
  
  
  /**
   * 創(chuàng)建觸發(fā)器
   * 第二種 方式 非常好
   * 可以 好用 2013年每月的第三個星期五上午10:30觸發(fā) 0 30 10 ? * 6#3 2013
   * 2016年每月的第一個星期四下午16:17觸發(fā)  0 17 16 ? * 5#1 2016
   * 每天15點到16點每5分鐘運(yùn)行一次,此外,每天17點到18點每5分鐘運(yùn)行一次 

   */
  /*CronTrigger trigger=TriggerBuilder.newTrigger() 
      .withIdentity("myTrigger", "myTriggerGroup")
      .withSchedule(CronScheduleBuilder.cronSchedule("0 18 16 ? * 5#1 2016")).build();*/
  
  SchedulerFactory sf=new StdSchedulerFactory();//創(chuàng)建調(diào)度者工廠
  Scheduler scheduler = sf.getScheduler();//創(chuàng)建一個調(diào)度者
  scheduler.scheduleJob(job,trigger);//注冊并進(jìn)行調(diào)度
  scheduler.start();//啟動調(diào)度
  
  //Thread.sleep(millis)
  
  //scheduler.shutdown();//關(guān)閉調(diào)度

RemindJob 類的定義

*/
public class RemindJob implements Job {
private RemindService service=new RemindService();
  @Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
    service.printPlan("你好!");
    
    Date date=new Date();
    String time = date.toString();
    System.out.println(time+"job is starting");
  }

可以看到,我們傳給scheduler一個JobDetail實例,因為我們在創(chuàng)建JobDetail時,將要執(zhí)行的job的類名傳給了JobDetail,所以scheduler就知道了要執(zhí)行何種類型的job;每次當(dāng)scheduler執(zhí)行job時,在調(diào)用其execute(…)方法之前會創(chuàng)建該類的一個新的實例;執(zhí)行完畢,對該實例的引用就被丟棄了,實例會被垃圾回收;這種執(zhí)行策略帶來的一個后果是,job必須有一個無參的構(gòu)造函數(shù)(當(dāng)使用默認(rèn)的JobFactory時);另一個后果是,在job類中,不應(yīng)該定義有狀態(tài)的數(shù)據(jù)屬性,因為在job的多次執(zhí)行中,這些屬性的值不會保留。

那么如何給job實例增加屬性或配置呢?如何在job的多次執(zhí)行中,跟蹤job的狀態(tài)呢?答案就是:JobDataMap,JobDetail對象的一部分。

JobDataMap

JobDataMap中可以包含不限量的(序列化的)數(shù)據(jù)對象,在job實例執(zhí)行的時候,可以使用其中的數(shù)據(jù);JobDataMap是Java Map接口的一個實現(xiàn),額外增加了一些便于存取基本類型的數(shù)據(jù)的方法。

將job加入到scheduler之前,在構(gòu)建JobDetail時,可以將數(shù)據(jù)放入JobDataMap,如下示例:

JobDetail job=JobBuilder.newJob(RemindJob.class)
      .withIdentity("job1", "group1")
      .usingJobData("hello", "we are family")
      .build();

在job的執(zhí)行過程中,可以從JobDataMap中取出數(shù)據(jù),如下示例:

@Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
    service.printPlan("你好!");
    JobKey key=context.getJobDetail().getKey();
    
    JobDataMap map = context.getJobDetail().getJobDataMap();
    String string = map.getString("hello");
    System.out.println(key+"==========="+string);
    
    Date date=new Date();
    String time = date.toString();
    System.out.println(time+"job is starting");
  }

如果你使用的是持久化的存儲機(jī)制(本教程的JobStore部分會講到),在決定JobDataMap中存放什么數(shù)據(jù)的時候需要小心,因為JobDataMap中存儲的對象都會被序列化,因此很可能會導(dǎo)致類的版本不一致的問題;Java的標(biāo)準(zhǔn)類型都很安全,如果你已經(jīng)有了一個類的序列化后的實例,某個時候,別人修改了該類的定義,此時你需要確保對類的修改沒有破壞兼容性;更多細(xì)節(jié),參考現(xiàn)實中的序列化問題。另外,你也可以配置JDBC-JobStore和JobDataMap,使得map中僅允許存儲基本類型和String類型的數(shù)據(jù),這樣可以避免后續(xù)的序列化問題。

如果你在job類中,為JobDataMap中存儲的數(shù)據(jù)的key增加set方法(如在上面示例中,增加setJobSays(String val)方法),那么Quartz的默認(rèn)JobFactory實現(xiàn)在job被實例化的時候會自動調(diào)用這些set方法,這樣你就不需要在execute()方法中顯式地從map中取數(shù)據(jù)了。

在Job執(zhí)行時,JobExecutionContext中的JobDataMap為我們提供了很多的便利。它是JobDetail中的JobDataMap和Trigger中的JobDataMap的并集,但是如果存在相同的數(shù)據(jù),則后者會覆蓋前者的值。

下面的示例,在job執(zhí)行時,從JobExecutionContext中獲取合并后的JobDataMap:

@Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
    service.printPlan("你好!");
    JobKey key=context.getJobDetail().getKey();
    
  /*  JobDataMap map = context.getJobDetail().getJobDataMap();
    String string = map.getString("hello");
    System.out.println(key+"==========="+string);*/


     JobDataMap map = context.getMergedJobDataMap();
     String string = map.getString("hello");
     System.out.println(key+"---------------------  "+string);

以上這篇Quartz之Job與JobDetail深入解析就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java完美實現(xiàn)2048小游戲

    Java完美實現(xiàn)2048小游戲

    本文給大家分享的是一則根據(jù)網(wǎng)友的代碼改編的2048小游戲的源碼,個人認(rèn)為已經(jīng)非常完美了,推薦給大家,有需要的小伙伴可以參考下。
    2015-03-03
  • Java的jmap命令的具體使用

    Java的jmap命令的具體使用

    jmap是JDK提供的一個可以生成Java虛擬機(jī)的堆轉(zhuǎn)儲快照dump文件的命令行工具,本文主要介紹了Java的jmap命令的具體使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Java如何通過反射方式生成數(shù)據(jù)庫實體類

    Java如何通過反射方式生成數(shù)據(jù)庫實體類

    這篇文章主要介紹了Java如何通過反射方式生成數(shù)據(jù)庫實體類問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • SpringBoot中實現(xiàn)代理方式

    SpringBoot中實現(xiàn)代理方式

    這篇文章主要介紹了SpringBoot中實現(xiàn)代理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java中的ArrayList和contains函數(shù)和擴(kuò)容機(jī)制(源碼詳解)

    Java中的ArrayList和contains函數(shù)和擴(kuò)容機(jī)制(源碼詳解)

    這篇文章主要介紹了Java中的ArrayList和contains函數(shù)和擴(kuò)容機(jī)制,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-10-10
  • 詳解Spring boot+CXF開發(fā)WebService Demo

    詳解Spring boot+CXF開發(fā)WebService Demo

    這篇文章主要介紹了詳解Spring boot+CXF開發(fā)WebService Demo,非常具有實用價值,需要的朋友可以參考下
    2017-05-05
  • java設(shè)計模式--建造者模式詳解

    java設(shè)計模式--建造者模式詳解

    這篇文章主要介紹了Java設(shè)計模式之建造者模式,結(jié)合具體實例形式分析了建造者模式的概念、原理、實現(xiàn)方法與相關(guān)使用注意事項,需要的朋友可以參考下
    2021-07-07
  • 實現(xiàn)一個基于Servlet的hello world程序詳解步驟

    實現(xiàn)一個基于Servlet的hello world程序詳解步驟

    Java Servlet 是運(yùn)行在 Web 服務(wù)器或應(yīng)用服務(wù)器上的程序,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務(wù)器上的數(shù)據(jù)庫或應(yīng)用程序之間的中間層
    2022-02-02
  • Spring?Boot的優(yōu)點及項目創(chuàng)建步驟詳解

    Spring?Boot的優(yōu)點及項目創(chuàng)建步驟詳解

    這篇文章主要介紹了Spring?Boot的優(yōu)點及項目創(chuàng)建步驟,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • Java中的RMI使用方法詳解

    Java中的RMI使用方法詳解

    這篇文章主要介紹了Java中的RMI使用方法,RMI是Java提供的一個完善的簡單易用的遠(yuǎn)程方法調(diào)用框架,采用客戶服務(wù)器通信方式,在服務(wù)器上部署了提供各種服務(wù)的遠(yuǎn)程對象,下面我們來詳細(xì)講解
    2023-10-10

最新評論