国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語(yǔ)言|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Springboot整合Quartz實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)的示例代碼

Springboot整合Quartz實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)的示例代碼

2021-06-02 13:54小揪揪 Java教程

這篇文章主要介紹了Springboot整合Quartz實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

簡(jiǎn)介

quartz是一款功能強(qiáng)大的任務(wù)調(diào)度器,可以實(shí)現(xiàn)較為復(fù)雜的調(diào)度功能,如每月一號(hào)執(zhí)行、每天凌晨執(zhí)行、每周五執(zhí)行等等,還支持分布式調(diào)度。本文使用springboot+mybatis+quartz實(shí)現(xiàn)對(duì)定時(shí)任務(wù)的增、刪、改、查、啟用、停用等功能。并把定時(shí)任務(wù)持久化到數(shù)據(jù)庫(kù)以及支持集群。

quartz的3個(gè)基本要素

  1. scheduler:調(diào)度器。所有的調(diào)度都是由它控制。
  2. trigger: 觸發(fā)器。決定什么時(shí)候來(lái)執(zhí)行任務(wù)。
  3. jobdetail & job: jobdetail定義的是任務(wù)數(shù)據(jù),而真正的執(zhí)行邏輯是在job中。使用jobdetail + job而不是job,這是因?yàn)槿蝿?wù)是有可能并發(fā)執(zhí)行,如果scheduler直接使用job,就會(huì)存在對(duì)同一個(gè)job實(shí)例并發(fā)訪問(wèn)的問(wèn)題。而jobdetail & job 方式,sheduler每次執(zhí)行,都會(huì)根據(jù)jobdetail創(chuàng)建一個(gè)新的job實(shí)例,這樣就可以規(guī)避并發(fā)訪問(wèn)的問(wèn)題。

如何使用quartz

1.添加依賴

?
1
2
3
4
5
6
7
8
9
10
<dependency>
  <groupid>org.quartz-scheduler</groupid>
  <artifactid>quartz</artifactid>
  <version>2.2.3</version>
</dependency>
<dependency>
  <groupid>org.quartz-scheduler</groupid>
  <artifactid>quartz-jobs</artifactid>
  <version>2.2.3</version>
</dependency>

2.創(chuàng)建配置文件

在maven項(xiàng)目的resource目錄下創(chuàng)建quartz.properties

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
org.quartz.scheduler.instancename = myscheduler
org.quartz.scheduler.instanceid = auto
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapjobexecutioninusertransaction = false
 
#線程池配置
org.quartz.threadpool.class = org.quartz.simpl.simplethreadpool
org.quartz.threadpool.threadcount = 10
org.quartz.threadpool.threadpriority = 5
org.quartz.threadpool.threadsinheritcontextclassloaderofinitializingthread = true
 
#持久化配置
org.quartz.jobstore.misfirethreshold = 50000
org.quartz.jobstore.class = org.quartz.impl.jdbcjobstore.jobstoretx
#支持集群
org.quartz.jobstore.isclustered = true
org.quartz.jobstore.useproperties:true
org.quartz.jobstore.clustercheckininterval = 15000
#使用weblogic連接oracle驅(qū)動(dòng)
org.quartz.jobstore.driverdelegateclass = org.quartz.impl.jdbcjobstore.oracle.weblogic.weblogicoracledelegate
#org.quartz.jobstore.driverdelegateclass = org.quartz.impl.jdbcjobstore.stdjdbcdelegate
org.quartz.jobstore.tableprefix = qrtz_
org.quartz.jobstore.datasource = qzds
#數(shù)據(jù)源連接信息,quartz默認(rèn)使用c3p0數(shù)據(jù)源可以被自定義數(shù)據(jù)源覆蓋
org.quartz.datasource.qzds.driver = oracle.jdbc.driver.oracledriver
org.quartz.datasource.qzds.url = jdbc:oracle:thin:@localhost:1521/xe
org.quartz.datasource.qzds.user = root
org.quartz.datasource.qzds.password = 123456
org.quartz.datasource.qzds.maxconnections = 10

說(shuō)明:在使用quartz做持久化的時(shí)候需要用到quartz的11張表,可以去quartz官網(wǎng)下載對(duì)應(yīng)版本的quartz,解壓打開(kāi)docs/dbtables里面有對(duì)應(yīng)數(shù)據(jù)庫(kù)的建表語(yǔ)句。關(guān)于quartz.properties配置的詳細(xì)解釋可以查看quartz官網(wǎng)。另外新建一張表tb_app_quartz用于存放定時(shí)任務(wù)基本信息和描述等信息,定時(shí)任務(wù)的增、刪、改、執(zhí)行等功能與此表沒(méi)有任何關(guān)系。
quartz的11張表:

Springboot整合Quartz實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)的示例代碼

?
1
2
3
4
5
6
7
8
9
10
//tb_app_quartz表的實(shí)體類
public class appquartz {
  private integer quartzid; //id 主鍵
  private string jobname; //任務(wù)名稱
  private string jobgroup; //任務(wù)分組
  private string starttime; //任務(wù)開(kāi)始時(shí)間
  private string cronexpression; //corn表達(dá)式
  private string invokeparam;//需要傳遞的參數(shù)
  ...省略set get
}

3.quartz配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * 創(chuàng)建job 實(shí)例工廠,解決spring注入問(wèn)題,如果使用默認(rèn)會(huì)導(dǎo)致spring的@autowired 無(wú)法注入問(wèn)題
 * @author llq
 *
 */
@component
public class jobfactory extends adaptablejobfactory{
  @autowired
  private autowirecapablebeanfactory capablebeanfactory;
  
   @override
    protected object createjobinstance(triggerfiredbundle bundle) throws exception {
      //調(diào)用父類的方法
      object jobinstance = super.createjobinstance(bundle);
      //進(jìn)行注入
      capablebeanfactory.autowirebean(jobinstance);
      return jobinstance;
    }
 
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
@configuration
public class schedulerconfig implements applicationlistener<contextrefreshedevent>{ 
  @autowired
  private jobfactory jobfactory;
  @autowired
  @qualifier("datasource")
  private datasource primarydatasource;
  
  @override
   public void onapplicationevent(contextrefreshedevent event) {
    system.out.println("任務(wù)已經(jīng)啟動(dòng)..."+event.getsource());
  }
  
  @bean
  public schedulerfactorybean schedulerfactorybean() throws ioexception {   
    //獲取配置屬性
    propertiesfactorybean propertiesfactorybean = new propertiesfactorybean();
    propertiesfactorybean.setlocation(new classpathresource("/quartz.properties"));
    //在quartz.properties中的屬性被讀取并注入后再初始化對(duì)象
    propertiesfactorybean.afterpropertiesset();
    //創(chuàng)建schedulerfactorybean
    schedulerfactorybean factory = new schedulerfactorybean();
    factory.setquartzproperties(propertiesfactorybean.getobject());
    //使用數(shù)據(jù)源,自定義數(shù)據(jù)源
    factory.setdatasource(this.primarydatasource);
    factory.setjobfactory(jobfactory);
    factory.setwaitforjobstocompleteonshutdown(true);//這樣當(dāng)spring關(guān)閉時(shí),會(huì)等待所有已經(jīng)啟動(dòng)的quartz job結(jié)束后spring才能完全shutdown。
    factory.setoverwriteexistingjobs(false);
    factory.setstartupdelay(1);
    return factory;
  }
  
  
  /*
   * 通過(guò)schedulerfactorybean獲取scheduler的實(shí)例
   */
  @bean(name="scheduler")
  public scheduler scheduler() throws ioexception {
    return schedulerfactorybean().getscheduler();
  }
  
  
  @bean
  public quartzinitializerlistener executorlistener() {
    return new quartzinitializerlistener();
  }
}

4.創(chuàng)建定時(shí)任務(wù)服務(wù)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
@service
public class jobutil {
   @autowired
   @qualifier("scheduler")
   private scheduler scheduler;
     
   
   /**
   * 新建一個(gè)任務(wù)
   *
   */  
   public string addjob(appquartz appquartz) throws exception {
     
       simpledateformat df = new simpledateformat("yyyy-mm-dd hh:mm:ss");
       date date=df.parse(appquartz.getstarttime());
     
       if (!cronexpression.isvalidexpression(appquartz.getcronexpression())) {     
        return "illegal cron expression"//表達(dá)式格式不正確
      }             
      jobdetail jobdetail=null;
      //構(gòu)建job信息
      if("jobone".equals(appquartz.getjobgroup())) {
         jobdetail = jobbuilder.newjob(jobone.class).withidentity(appquartz.getjobname(), appquartz.getjobgroup()).build();
      }
      if("jobtwo".equals(appquartz.getjobgroup())) {
         jobdetail = jobbuilder.newjob(jobtwo.class).withidentity(appquartz.getjobname(), appquartz.getjobgroup()).build();
      }
          
      //表達(dá)式調(diào)度構(gòu)建器(即任務(wù)執(zhí)行的時(shí)間,不立即執(zhí)行)
      cronschedulebuilder schedulebuilder = cronschedulebuilder.cronschedule(appquartz.getcronexpression()).withmisfirehandlinginstructiondonothing();
 
      //按新的cronexpression表達(dá)式構(gòu)建一個(gè)新的trigger
      crontrigger trigger = triggerbuilder.newtrigger().withidentity(appquartz.getjobname(), appquartz.getjobgroup()).startat(date)
          .withschedule(schedulebuilder).build();
                 
      //傳遞參數(shù)
      if(appquartz.getinvokeparam()!=null && !"".equals(appquartz.getinvokeparam())) {
        trigger.getjobdatamap().put("invokeparam",appquartz.getinvokeparam()); 
      }               
      scheduler.schedulejob(jobdetail, trigger);
      // pausejob(appquartz.getjobname(),appquartz.getjobgroup());
      return "success";
    }
     /**
     * 獲取job狀態(tài)
     * @param jobname
     * @param jobgroup
     * @return
     * @throws schedulerexception
     */
     public string getjobstate(string jobname, string jobgroup) throws schedulerexception {      
       triggerkey triggerkey = new triggerkey(jobname, jobgroup); 
       return scheduler.gettriggerstate(triggerkey).name();
      }
     
     //暫停所有任務(wù)
     public void pausealljob() throws schedulerexception {     
       scheduler.pauseall();
     }
    
    //暫停任務(wù)
    public string pausejob(string jobname, string jobgroup) throws schedulerexception {     
      jobkey jobkey = new jobkey(jobname, jobgroup);
      jobdetail jobdetail = scheduler.getjobdetail(jobkey);
      if (jobdetail == null) {
         return "fail";
      }else {
         scheduler.pausejob(jobkey);
         return "success";
      }
                     
    }
    
    //恢復(fù)所有任務(wù)
    public void resumealljob() throws schedulerexception {     
      scheduler.resumeall();
    }
    
    // 恢復(fù)某個(gè)任務(wù)
    public string resumejob(string jobname, string jobgroup) throws schedulerexception {
      
      jobkey jobkey = new jobkey(jobname, jobgroup);
      jobdetail jobdetail = scheduler.getjobdetail(jobkey);
      if (jobdetail == null) {
        return "fail";
      }else {       
        scheduler.resumejob(jobkey);
        return "success";
      }
    }
    
    //刪除某個(gè)任務(wù)
    public string deletejob(appquartz appquartz) throws schedulerexception {     
      jobkey jobkey = new jobkey(appquartz.getjobname(), appquartz.getjobgroup());
      jobdetail jobdetail = scheduler.getjobdetail(jobkey);
      if (jobdetail == null ) {
         return "jobdetail is null";
      }else if(!scheduler.checkexists(jobkey)) {
        return "jobkey is not exists";
      }else {
         scheduler.deletejob(jobkey);
         return "success";
      }
      
    }
    
    //修改任務(wù)
    public string modifyjob(appquartz appquartz) throws schedulerexception {     
      if (!cronexpression.isvalidexpression(appquartz.getcronexpression())) {
        return "illegal cron expression";
      }
      triggerkey triggerkey = triggerkey.triggerkey(appquartz.getjobname(),appquartz.getjobgroup());     
      jobkey jobkey = new jobkey(appquartz.getjobname(),appquartz.getjobgroup());
      if (scheduler.checkexists(jobkey) && scheduler.checkexists(triggerkey)) {
        crontrigger trigger = (crontrigger) scheduler.gettrigger(triggerkey);     
        //表達(dá)式調(diào)度構(gòu)建器,不立即執(zhí)行
        cronschedulebuilder schedulebuilder = cronschedulebuilder.cronschedule(appquartz.getcronexpression()).withmisfirehandlinginstructiondonothing();
        //按新的cronexpression表達(dá)式重新構(gòu)建trigger
        trigger = trigger.gettriggerbuilder().withidentity(triggerkey)
          .withschedule(schedulebuilder).build();
        //修改參數(shù)
        if(!trigger.getjobdatamap().get("invokeparam").equals(appquartz.getinvokeparam())) {
          trigger.getjobdatamap().put("invokeparam",appquartz.getinvokeparam());
        }       
        //按新的trigger重新設(shè)置job執(zhí)行
        scheduler.reschedulejob(triggerkey, trigger);                       
        return "success";         
      }else {
        return "job or trigger not exists";
      
      
    }
 
}
?
1
2
3
4
5
6
7
8
9
10
11
@persistjobdataafterexecution
@disallowconcurrentexecution
@component
public class jonone implements job{
  @override
  public void execute(jobexecutioncontext context) throws jobexecutionexception{
    jobdatamap data=context.gettrigger().getjobdatamap();
    string invokeparam =(string) data.get("invokeparam");
    //在這里實(shí)現(xiàn)業(yè)務(wù)邏輯
    }
}
?
1
2
3
4
5
6
7
8
9
10
11
@persistjobdataafterexecution
@disallowconcurrentexecution
@component
public class jobtwo implements job{
  @override
  public void execute(jobexecutioncontext context) throws jobexecutionexception{
    jobdatamap data=context.gettrigger().getjobdatamap();
    string invokeparam =(string) data.get("invokeparam");
    //在這里實(shí)現(xiàn)業(yè)務(wù)邏輯
    }
}

說(shuō)明:每個(gè)定時(shí)任務(wù)都必須有一個(gè)分組,名稱和corn表達(dá)式,corn表達(dá)式也就是定時(shí)任務(wù)的觸發(fā)時(shí)間,關(guān)于corn表達(dá)式格式以及含義可以參考一些網(wǎng)絡(luò)資源。每個(gè)定時(shí)任務(wù)都有一個(gè)入口類在這里我把類名當(dāng)成定時(shí)任務(wù)的分組名稱,例如:只要?jiǎng)?chuàng)建定時(shí)任務(wù)的分組是jobone的都會(huì)執(zhí)行jobone這個(gè)任務(wù)類里面的邏輯。如果定時(shí)任務(wù)需要額外的參數(shù)可以使用jobdatamap傳遞參數(shù),當(dāng)然也可以從數(shù)據(jù)庫(kù)中獲取需要的數(shù)據(jù)。@persistjobdataafterexecution和@disallowconcurrentexecution注解是不讓某個(gè)定時(shí)任務(wù)并發(fā)執(zhí)行,只有等當(dāng)前任務(wù)完成下一個(gè)任務(wù)才會(huì)去執(zhí)行。

5.封裝定時(shí)任務(wù)接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
@restcontroller
public class jobcontroller {
  @autowired
  private jobutil jobutil; 
  @autowired
  private appquartzservice appquartzservice;
  
  
  //添加一個(gè)job
  @requestmapping(value="/addjob",method=requestmethod.post)
  public returnmsg addjob(@requestbody appquartz appquartz) throws exception { 
    appquartzservice.insertappquartzser(appquartz);   
    result=jobutil.addjob(appquartz);                       
  }
  
  //暫停job 
  @requestmapping(value="/pausejob",method=requestmethod.post)
  public returnmsg pausejob(@requestbody integer[]quartzids) throws exception { 
    appquartz appquartz=null;     
    if(quartzids.length>0){
      for(integer quartzid:quartzids) {
        appquartz=appquartzservice.selectappquartzbyidser(quartzid).get(0);
        jobutil.pausejob(appquartz.getjobname(), appquartz.getjobgroup());           
      }
      return new returnmsg("200","success pausejob"); 
    }else {
      return new returnmsg("404","fail pausejob"); 
    }                               
  }
  
  //恢復(fù)job
  @requestmapping(value="/resumejob",method=requestmethod.post)
  public returnmsg resumejob(@requestbody integer[]quartzids) throws exception { 
    appquartz appquartz=null;
    if(quartzids.length>0) {
      for(integer quartzid:quartzids) {
        appquartz=appquartzservice.selectappquartzbyidser(quartzid).get(0);
        jobutil.resumejob(appquartz.getjobname(), appquartz.getjobgroup());       
      }
      return new returnmsg("200","success resumejob");
    }else {
      return new returnmsg("404","fail resumejob");
    }     
  }
    
  
  //刪除job
  @requestmapping(value="/deletjob",method=requestmethod.post)
  public returnmsg deletjob(@requestbody integer[]quartzids) throws exception {
    appquartz appquartz=null;
    for(integer quartzid:quartzids) {
      appquartz=appquartzservice.selectappquartzbyidser(quartzid).get(0);
      string ret=jobutil.deletejob(appquartz);
      if("success".equals(ret)) {
        appquartzservice.deleteappquartzbyidser(quartzid);
      }
    }
    return new returnmsg("200","success deletejob"); 
  }
    
  //修改
  @requestmapping(value="/updatejob",method=requestmethod.post)
  public returnmsg modifyjob(@requestbody appquartz appquartz) throws exception {
    string ret= jobutil.modifyjob(appquartz);     
    if("success".equals(ret)) {     
      appquartzservice.updateappquartzser(appquartz);
      return new returnmsg("200","success updatejob",ret);
    }else {
      return new returnmsg("404","fail updatejob",ret);
    }       
  }
  
  //暫停所有
  @requestmapping(value="/pauseall",method=requestmethod.get)
  public returnmsg pausealljob() throws exception {
    jobutil.pausealljob();
    return new returnmsg("200","success pauseall");
  }
  
  //恢復(fù)所有
  @requestmapping(value="/repauseall",method=requestmethod.get)
  public returnmsg repausealljob() throws exception {
    jobutil.resumealljob();
    return new returnmsg("200","success repauseall");
  
  
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://segmentfault.com/a/1190000016554033

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91精品国产日韩91久久久久久 | 国产成人精品一区二区三区视频 | 成人天堂666 | 一区二区三区在线免费播放 | www久| 国产淫片 | 午夜免费av | 午夜在线电影 | 日韩国产欧美视频 | 成人久久久久久 | 国产精品久久久久久久久免费桃花 | 国产精品毛片久久久久久久 | 久久精品一 | 深夜福利影院 | 超碰97人人干 | 日韩欧美手机在线 | 欧美视频一区二区 | 操操网站| 久久久91精品国产一区二区三区 | av一区二区在线观看 | 国产精品一区二区三区四区 | 久久久精品呻吟 | 欧美日韩精品电影 | 亚洲精品视频免费 | 国产一区二区视频在线观看 | 一级黄色免费毛片 | porn亚洲| 国产麻豆乱码精品一区二区三区 | 亚洲国产一区二区三区在线播放 | 国产精品视频一区二区三区不卡 | 久久久久国产一区二区三区四区 | 免费观看国产精品 | 亚洲一区 中文字幕 | 国产高清一 | 日韩福利在线 | 亚洲精品一区二区三区蜜桃下载 | 成人精品视频免费 | 久久水蜜桃 | 久久久国产精品入口麻豆 | 成人天堂网| 国产欧美精品一区二区色综合 |