中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在springboot中利用Quartz實現一個定時任務功能

發布時間:2020-12-08 16:28:40 來源:億速云 閱讀:186 作者:Leah 欄目:編程語言

如何在springboot中利用Quartz實現一個定時任務功能?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

一、新建一個springboot工程,并添加依賴

<dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-jpa</artifactId> 
    </dependency> 
 
    <dependency><!-- 為了方便測試,此處使用了內存數據庫 --> 
      <groupId>com.h3database</groupId> 
      <artifactId>h3</artifactId> 
      <scope>runtime</scope> 
    </dependency> 
    <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-test</artifactId> 
      <scope>test</scope> 
    </dependency> 
     
    <dependency> 
      <groupId>org.quartz-scheduler</groupId> 
      <artifactId>quartz</artifactId> 
      <version>2.2.1</version> 
      <exclusions> 
        <exclusion> 
          <artifactId>slf4j-api</artifactId> 
          <groupId>org.slf4j</groupId> 
        </exclusion> 
      </exclusions> 
    </dependency> 
    <dependency><!-- 該依賴必加,里面有sping對schedule的支持 --> 
            <groupId>org.springframework</groupId> 
            <artifactId>spring-context-support</artifactId> 
    </dependency> 

二、配置文件application.properties

# 服務器端口號  
server.port=7902 
# 是否生成ddl語句  
spring.jpa.generate-ddl=false  
# 是否打印sql語句  
spring.jpa.show-sql=true  
# 自動生成ddl,由于指定了具體的ddl,此處設置為none  
spring.jpa.hibernate.ddl-auto=none  
# 使用H2數據庫  
spring.datasource.platform=h3  
# 指定生成數據庫的schema文件位置  
spring.datasource.schema=classpath:schema.sql  
# 指定插入數據庫語句的腳本位置  
spring.datasource.data=classpath:data.sql  
# 配置日志打印信息  
logging.level.root=INFO  
logging.level.org.hibernate=INFO  
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE  
logging.level.org.hibernate.type.descriptor.sql.BasicExtractor=TRACE  
logging.level.com.itmuch=DEBUG  

三、Entity類

package com.chhliu.springboot.quartz.entity; 
 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
 
@Entity 
public class Config { 
  @Id 
   @GeneratedValue(strategy = GenerationType.AUTO) 
   private Long id; 
 
   @Column 
   private String cron; 
 
  /** 
   * @return the id 
   */ 
  public Long getId() { 
    return id; 
  } 
    ……此處省略getter和setter方法…… 
} 

四、任務類

package com.chhliu.springboot.quartz.entity; 
 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.scheduling.annotation.EnableScheduling; 
import org.springframework.stereotype.Component; 
 
@Configuration 
@Component // 此注解必加 
@EnableScheduling // 此注解必加 
public class ScheduleTask { 
  private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleTask.class); 
  public void sayHello(){ 
    LOGGER.info("Hello world, i'm the king of the world!!!"); 
  } 
} 

五、Quartz配置類

由于springboot追求零xml配置,所以下面會以配置Bean的方式來實現

package com.chhliu.springboot.quartz.entity; 
 
import org.quartz.Trigger; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.scheduling.quartz.CronTriggerFactoryBean; 
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean; 
import org.springframework.scheduling.quartz.SchedulerFactoryBean; 
 
@Configuration 
public class QuartzConfigration { 
  /** 
   * attention: 
   * Details:配置定時任務 
   */ 
  @Bean(name = "jobDetail") 
  public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduleTask task) {// ScheduleTask為需要執行的任務 
    MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean(); 
    /* 
     * 是否并發執行 
     * 例如每5s執行一次任務,但是當前任務還沒有執行完,就已經過了5s了, 
     * 如果此處為true,則下一個任務會執行,如果此處為false,則下一個任務會等待上一個任務執行完后,再開始執行 
     */ 
    jobDetail.setConcurrent(false); 
     
    jobDetail.setName("srd-chhliu");// 設置任務的名字 
    jobDetail.setGroup("srd");// 設置任務的分組,這些屬性都可以存儲在數據庫中,在多任務的時候使用 
     
    /* 
     * 為需要執行的實體類對應的對象 
     */ 
    jobDetail.setTargetObject(task); 
     
    /* 
     * sayHello為需要執行的方法 
     * 通過這幾個配置,告訴JobDetailFactoryBean我們需要執行定時執行ScheduleTask類中的sayHello方法 
     */ 
    jobDetail.setTargetMethod("sayHello"); 
    return jobDetail; 
  } 
   
  /** 
   * attention: 
   * Details:配置定時任務的觸發器,也就是什么時候觸發執行定時任務 
   */ 
  @Bean(name = "jobTrigger") 
  public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) { 
    CronTriggerFactoryBean tigger = new CronTriggerFactoryBean(); 
    tigger.setJobDetail(jobDetail.getObject()); 
    tigger.setCronExpression("0 30 20 * * &#63;");// 初始時的cron表達式 
    tigger.setName("srd-chhliu");// trigger的name 
    return tigger; 
 
  } 
 
  /** 
   * attention: 
   * Details:定義quartz調度工廠 
   */ 
  @Bean(name = "scheduler") 
  public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) { 
    SchedulerFactoryBean bean = new SchedulerFactoryBean(); 
    // 用于quartz集群,QuartzScheduler 啟動時更新己存在的Job 
    bean.setOverwriteExistingJobs(true); 
    // 延時啟動,應用啟動1秒后 
    bean.setStartupDelay(1); 
    // 注冊觸發器 
    bean.setTriggers(cronJobTrigger); 
    return bean; 
  } 
} 

六、定時查庫,并更新任務

package com.chhliu.springboot.quartz.entity; 
 
import javax.annotation.Resource; 
 
import org.quartz.CronScheduleBuilder; 
import org.quartz.CronTrigger; 
import org.quartz.JobDetail; 
import org.quartz.Scheduler; 
import org.quartz.SchedulerException; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.scheduling.annotation.EnableScheduling; 
import org.springframework.scheduling.annotation.Scheduled; 
import org.springframework.stereotype.Component; 
 
import com.chhliu.springboot.quartz.repository.ConfigRepository; 
 
@Configuration 
@EnableScheduling 
@Component 
public class ScheduleRefreshDatabase { 
  @Autowired 
  private ConfigRepository repository; 
 
  @Resource(name = "jobDetail") 
  private JobDetail jobDetail; 
 
  @Resource(name = "jobTrigger") 
  private CronTrigger cronTrigger; 
 
  @Resource(name = "scheduler") 
  private Scheduler scheduler; 
 
  @Scheduled(fixedRate = 5000) // 每隔5s查庫,并根據查詢結果決定是否重新設置定時任務 
  public void scheduleUpdateCronTrigger() throws SchedulerException { 
    CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey()); 
    String currentCron = trigger.getCronExpression();// 當前Trigger使用的 
    String searchCron = repository.findOne(1L).getCron();// 從數據庫查詢出來的 
    System.out.println(currentCron); 
    System.out.println(searchCron); 
    if (currentCron.equals(searchCron)) { 
      // 如果當前使用的cron表達式和從數據庫中查詢出來的cron表達式一致,則不刷新任務 
    } else { 
      // 表達式調度構建器 
      CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron); 
      // 按新的cronExpression表達式重新構建trigger 
      trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey()); 
      trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey()) 
          .withSchedule(scheduleBuilder).build(); 
      // 按新的trigger重新設置job執行 
      scheduler.rescheduleJob(cronTrigger.getKey(), trigger); 
      currentCron = searchCron; 
    } 
  } 
} 

六、相關腳本

1、data.sql

insert into config(id,cron) values(1,'0 0/2 * * * &#63;'); # 每2分鐘執行一次定時任務

2、schema.sql

drop table config if exists; 
create table config( 
  id bigint generated by default as identity, 
  cron varchar(40), 
  primary key(id) 
); 

六、運行測試

測試結果如下:(Quartz默認的線程池大小為10)

0 30 20 * * &#63; 
0 0/2 * * * &#63; 
2017-03-08 18:02:00.025 INFO 5328 --- [eduler_Worker-1] c.c.s.quartz.entity.ScheduleTask     : Hello world, i'm the king of the world!!! 
2017-03-08 18:04:00.003 INFO 5328 --- [eduler_Worker-2] c.c.s.quartz.entity.ScheduleTask     : Hello world, i'm the king of the world!!! 
2017-03-08 18:06:00.002 INFO 5328 --- [eduler_Worker-3] c.c.s.quartz.entity.ScheduleTask     : Hello world, i'm the king of the world!!! 
2017-03-08 18:08:00.002 INFO 5328 --- [eduler_Worker-4] c.c.s.quartz.entity.ScheduleTask     : Hello world, i'm the king of the world!!! 

從上面的日志打印時間來看,我們實現了動態配置,最初的時候,任務是每天20:30執行,后面通過動態刷新變成了每隔2分鐘執行一次。

雖然上面的解決方案沒有使用Quartz推薦的方式完美,但基本上可以滿足我們的需求,當然也可以采用觸發事件的方式來實現,例如當前端修改定時任務的觸發時間時,異步的向后臺發送通知,后臺收到通知后,然后再更新程序,也可以實現動態的定時任務刷新

看完上述內容,你們掌握如何在springboot中利用Quartz實現一個定時任務功能的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

衢州市| 东辽县| 灵丘县| 湘潭市| 诏安县| 宁河县| 温泉县| 成武县| 塘沽区| 德兴市| 皮山县| 衢州市| 慈利县| 美姑县| 大埔区| 高雄县| 罗田县| 桃江县| 望城县| 锦屏县| 拉萨市| 禄丰县| 玉树县| 日土县| 乌恰县| 曲水县| 平舆县| 永泰县| 山阴县| 梁河县| 芜湖市| 普陀区| 子长县| 安达市| 体育| 淄博市| 丰镇市| 蒙山县| 桐庐县| 乃东县| 伊春市|