最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Quartz實(shí)現(xiàn)JAVA定時(shí)任務(wù)的動(dòng)態(tài)配置的方法

 更新時(shí)間:2018年07月24日 14:32:23   作者:小賣鋪的老爺爺  
這篇文章主要介紹了Quartz實(shí)現(xiàn)JAVA定時(shí)任務(wù)的動(dòng)態(tài)配置的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

先說點(diǎn)無關(guān)本文的問題,這段時(shí)間特別的不爽,可能有些同學(xué)也遇到過。其實(shí)也可以說是小事一樁,但感覺也是不容忽視的。我剛畢業(yè)時(shí)的公司,每個(gè)人每次提交代碼都有著嚴(yán)格的規(guī)范,像table和space的縮進(jìn)都有嚴(yán)格的要求,可以說你不遵守開發(fā)規(guī)范就相當(dāng)于線上bug問題,還是比較嚴(yán)重的?,F(xiàn)在發(fā)現(xiàn)外面的公司真的是沒那么重視這個(gè)不重要卻又特別重要的問題啊,啊啊啊啊啊?。。。?/p>

什么是動(dòng)態(tài)配置定時(shí)任務(wù)?

回歸正題,說下這次主題,動(dòng)態(tài)配置。沒接觸過定時(shí)任務(wù)的同學(xué)可以先看下此篇:JAVA定時(shí)任務(wù)實(shí)現(xiàn)的幾種方式

定時(shí)任務(wù)實(shí)現(xiàn)方式千人千種,不過基礎(chǔ)的無外乎 1、JDK 的Timer類 2、Quartz 3、SpringTask  。生產(chǎn)上三種方式我都有使用過。但是使用過程中用的最多的便是xml配置的方式,這種方式最簡單,無代碼侵入,也比較好理解。

但是卻有個(gè)致命的缺點(diǎn),比如你要改某個(gè)任務(wù)的觸發(fā)時(shí)間,亦或是你要新增一個(gè)任務(wù),暫停一個(gè)任務(wù)。怎么做?

停應(yīng)用!改XML配置!重新啟動(dòng)!

是不是很致命。最近重新研究了下Quartz的配置,實(shí)現(xiàn)了不停機(jī)添加、暫停、刪除、立即觸發(fā)任務(wù)的方法,在本篇分享出來,其實(shí)也不算是完全的研究,在上家公司已經(jīng)有大佬實(shí)現(xiàn)了,這次是也是基于大佬的理解重新實(shí)現(xiàn)下。

國際慣例~先看效果圖   ps:文末有彩蛋哦~~

管理界面:

效果圖:實(shí)在不知道該跑什么了,每隔十秒打一段話吧

 

技術(shù)實(shí)現(xiàn) maven依賴

使用springboot做框架支持

<!-- quartz -->
<dependency>
 <groupId>org.quartz-scheduler</groupId>
 <artifactId>quartz</artifactId>
 <version>2.2.1</version>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context-support</artifactId>
</dependency>

數(shù)據(jù)表

CREATE TABLE `sys_task` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `job_name` varchar(255) DEFAULT NULL COMMENT '任務(wù)名',
 `description` varchar(255) DEFAULT NULL COMMENT '任務(wù)描述',
 `cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron表達(dá)式',
 `bean_class` varchar(255) DEFAULT NULL COMMENT '任務(wù)執(zhí)行時(shí)調(diào)用哪個(gè)類的方法 包名+類名',
 `job_status` varchar(255) DEFAULT NULL COMMENT '任務(wù)狀態(tài)',
 `job_group` varchar(255) DEFAULT NULL COMMENT '任務(wù)分組',
 `create_user` varchar(64) DEFAULT NULL COMMENT '創(chuàng)建者',
 `create_time` datetime DEFAULT NULL COMMENT '創(chuàng)建時(shí)間',
 `update_user` varchar(64) DEFAULT NULL COMMENT '更新者',
 `update_time` datetime DEFAULT NULL COMMENT '更新時(shí)間',
 PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;

實(shí)現(xiàn)步驟

①啟動(dòng)項(xiàng)目,啟動(dòng)task監(jiān)聽

②讀取數(shù)據(jù)庫,將開啟的任務(wù)job和trigger加載到scheduler調(diào)度器

③根據(jù)任務(wù)調(diào)度運(yùn)行job類

④每次運(yùn)行利用AdaptableJobFactory實(shí)例化job類,以便注入要運(yùn)行的service

聽著是不是很簡單,但卻還是一頭霧水,且聽我慢慢道來~~

代碼邏輯

第一步:啟動(dòng)項(xiàng)目,加載監(jiān)聽

Quartz配置

Springboot的配置方法,常規(guī)Spring項(xiàng)目可以在xml中配置

@Configuration
public class QuartzConfigration {

 @Autowired
 private JobFactory jobFactory;

 @Bean
 public SchedulerFactoryBean schedulerFactoryBean() {
  SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
  try {
   schedulerFactoryBean.setOverwriteExistingJobs(true);
   schedulerFactoryBean.setQuartzProperties(quartzProperties());
   schedulerFactoryBean.setJobFactory(jobFactory);
  } catch (Exception e) {
   e.printStackTrace();
  }
  return schedulerFactoryBean;
 }

 // 指定quartz.properties,可在配置文件中配置相關(guān)屬性
 @Bean
 public Properties quartzProperties() throws IOException {
  PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
  propertiesFactoryBean.setLocation(new ClassPathResource("/config/quartz.properties"));
  propertiesFactoryBean.afterPropertiesSet();
  return propertiesFactoryBean.getObject();
 }

 // 創(chuàng)建schedule
 @Bean(name = "scheduler")
 public Scheduler scheduler() {
  return schedulerFactoryBean().getScheduler();
 }
}

監(jiān)聽器

@Component
@Order(value = 1)
public class ScheduleJobInitListener implements CommandLineRunner {

 @Autowired
 TaskService scheduleJobService;

 @Override
 public void run(String... arg0) throws Exception {
  try {
   scheduleJobService.initSchedule();
  } catch (Exception e) {
   e.printStackTrace();
  }

 }

}

CommandLineRunner類似Spring框架的ApplicationListener監(jiān)聽器。

官方的解釋是:

Interface used to indicate that a bean should run when it is contained within a SpringApplication. Multiple CommandLineRunner beans can be defined within the same application context and can be ordered using the Ordered interface or Order @Order annotation.

第二步:讀取數(shù)據(jù)庫,加載scheduler調(diào)度器

job方法

@Override
 public void initSchedule() throws SchedulerException {
  // 這里獲取任務(wù)信息數(shù)據(jù)
  List<TaskDO> jobList = taskMapper.list();
  for (TaskDO task : jobList) {
   if (JobStatusEnum.RUNNING.getCode().equals(task.getJobStatus())) {
    quartzManager.addJob(task);
   }
  }
 }

添加任務(wù)到Quartz調(diào)度器

/**
  * 添加任務(wù)*/ 
 @SuppressWarnings("unchecked")
 public void addJob(TaskDO task) {
  try {
   // 創(chuàng)建jobDetail實(shí)例,綁定Job實(shí)現(xiàn)類
   // 指明job的名稱,所在組的名稱,以及綁定job類
   Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(task.getBeanClass()).newInstance()
     .getClass());
   JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(task.getJobName(), task.getJobGroup())// 任務(wù)名稱和組構(gòu)成任務(wù)key
     .build();
   // 定義調(diào)度觸發(fā)規(guī)則
   // 使用cornTrigger規(guī)則
   Trigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(), task.getJobGroup())// 觸發(fā)器key
     .startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
     .withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).startNow().build();
   // 把作業(yè)和觸發(fā)器注冊到任務(wù)調(diào)度中
   scheduler.scheduleJob(jobDetail, trigger);
   // 啟動(dòng)
   if (!scheduler.isShutdown()) {
    scheduler.start();
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

Scheduler作為Quartz的核心調(diào)度器,有將近50多個(gè)API接口,包括任務(wù)的添加,暫停,恢復(fù),刪除等一系列的API,這里僅介紹一些常用的,想要了解更多可以稍后看下彩蛋部分。

1、start()方法:只有調(diào)用start()方法后,Scheduler線程才開始啟動(dòng)觸發(fā)器trigger,運(yùn)行job

2、pauseJob(JobKey jobKey) :根據(jù)指定的JobDetail key暫停job。

3、resumeJob(JobKey jobKey) :根據(jù)指定的key恢復(fù)一個(gè)job。

4、deleteJob(JobKey jobKey) :刪除一個(gè)job

5、triggerJob(JobKey jobKey) :觸發(fā)一個(gè)JobDetail(現(xiàn)在執(zhí)行)。

6、rescheduleJob(TriggerKey triggerKey, Trigger newTrigger):

用給定的鍵刪除觸發(fā)器,并存儲(chǔ)新的觸發(fā)器,它必須與同一個(gè)作業(yè)相關(guān)聯(lián)(新觸發(fā)器必須具有指定的作業(yè)名和組)-然而,新觸發(fā)器不必具有與舊觸發(fā)器相同的名稱。

第三步:根據(jù)任務(wù)調(diào)度運(yùn)行job類

其實(shí)這一步是不需要我們編寫的,在我們將正確的JobDetail 和 Trigger 表達(dá)式加載到任務(wù)調(diào)度后,調(diào)度器會(huì)自動(dòng)觸發(fā)任務(wù)的執(zhí)行

第四步:實(shí)例化job類,注入要運(yùn)行的service

工廠類

@Component
public class JobFactory extends AdaptableJobFactory {
 //這個(gè)對象Spring會(huì)幫我們自動(dòng)注入進(jìn)來,也屬于Spring技術(shù)范疇.
 //為什么需要這個(gè)類呢,在我寫的這個(gè)demo中,大家可以將此類刪掉,發(fā)現(xiàn)程序也可以正確運(yùn)行,可是我為什么還是加上呢。
 //大家可以看下我們的任務(wù)類,大家可以看到Job對象的實(shí)例化過程是在Quartz中進(jìn)行的,這時(shí)候我們將spring的東西注入進(jìn)來,肯定是行不通的,所以需要這個(gè)類
 @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;
 }
}

任務(wù)類

@DisallowConcurrentExecution //作業(yè)不并發(fā)
@Component
public class HelloWorldJob implements Job{

 @Override
 public void execute(JobExecutionContext arg0) throws JobExecutionException {
  
  System.out.println("歡迎使用yyblog,這是一個(gè)定時(shí)任務(wù) --小賣鋪的老爺爺!"+ DateUtils.fullTime(new Date()));
  
 }

}

好了,大功告成,一個(gè)簡單的動(dòng)態(tài)配置的定時(shí)任務(wù)已經(jīng)完成。是不是so easy,下面我們再來簡單實(shí)現(xiàn)下其他的幾種常用的api吧。

暫停一個(gè)job

public void pauseJob(TaskDO task) throws SchedulerException {
  JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
  scheduler.pauseJob(jobKey);
 }

恢復(fù)一個(gè)job

 public void resumeJob(TaskDO task) throws SchedulerException {
  JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
  scheduler.resumeJob(jobKey);
 }

刪除一個(gè)job

 public void deleteJob(TaskDO task) throws SchedulerException {
  JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
  scheduler.deleteJob(jobKey);
 }

立即觸發(fā)job

public void runJobNow(TaskDO task) throws SchedulerException {
  JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());
  scheduler.triggerJob(jobKey);
 }

更新job表達(dá)式

public void updateJobCron(TaskDO task) throws SchedulerException {

  TriggerKey triggerKey = TriggerKey.triggerKey(task.getJobName(), task.getJobGroup());

  CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

  CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCronExpression());

  trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

  scheduler.rescheduleJob(triggerKey, trigger);
 }

彩蛋部分~

好了,正文部分基本上就這些,不多廢話了,本文沒有太多的講解原理,只是簡單的應(yīng)用,水平不夠還望大家見諒。

看了上面的效果圖是不是還是有種看的見摸不著的感覺,老爺爺這里也做了個(gè)線上的實(shí)例供大家體驗(yàn)~有興趣的同學(xué)可以親自試驗(yàn)一下。

實(shí)例地址: http://www.laoyeye.net/management/index 賬號(hào)/密碼:test/123456  菜單:系統(tǒng)設(shè)置/計(jì)劃任務(wù)

當(dāng)然了還有最重要的源碼和API文檔我也不會(huì)忘的。

源碼地址: https://github.com/allanzhuo/yyblog

Quartz文檔地址: https://github.com/allanzhuo/yyblog/tree/master/doc

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解Spring bean的注解注入之@Autowired的原理及使用

    詳解Spring bean的注解注入之@Autowired的原理及使用

    之前講過bean注入是什么,也使用了xml的配置文件進(jìn)行bean注入,這也是Spring的最原始的注入方式(xml注入).本文主要講解的注解有以下幾個(gè):@Autowired、 @Service、@Repository、@Controller 、@Component、@Bean、@Configuration、@Resource ,需要的朋友可以參考下
    2021-06-06
  • 基于Tomcat7、Java、WebSocket的服務(wù)器推送聊天室實(shí)例

    基于Tomcat7、Java、WebSocket的服務(wù)器推送聊天室實(shí)例

    HTML5 WebSocket實(shí)現(xiàn)了服務(wù)器與瀏覽器的雙向通訊,本篇文章主要介紹了基于Tomcat7、Java、WebSocket的服務(wù)器推送聊天室實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2016-12-12
  • 學(xué)習(xí)Java之File文件操作方法

    學(xué)習(xí)Java之File文件操作方法

    這篇文章我們主要學(xué)習(xí)如何實(shí)現(xiàn)IO流的具體操作,但很多時(shí)候,IO流都會(huì)操作一個(gè)文件,所以我們需要先學(xué)習(xí)在Java中如何操作文件,包括文件及文件夾的創(chuàng)建、遍歷、刪除等,有了文件操作的基礎(chǔ),我們才能更好地操作IO流,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-09-09
  • java內(nèi)部測試類代碼詳解

    java內(nèi)部測試類代碼詳解

    這篇文章主要介紹了java內(nèi)部測試類代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • 解決IDEA中 Ctrl+ALT+V這個(gè)快捷鍵無法使用的情況

    解決IDEA中 Ctrl+ALT+V這個(gè)快捷鍵無法使用的情況

    這篇文章主要介紹了解決IDEA中 Ctrl+ALT+V這個(gè)快捷鍵無法使用的情況,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Resttemplate上傳文件500異常的原因及解決方法

    Resttemplate上傳文件500異常的原因及解決方法

    使用 Resttemplate 調(diào)用 DMS 文件服務(wù)器 Http 接口,出現(xiàn) 500 異常報(bào)錯(cuò),所以本文給大家介紹了Resttemplate上傳文件500異常的原因及解決方法,需要的朋友可以參考下
    2024-08-08
  • Java的logback自定義日志脫敏組件詳解

    Java的logback自定義日志脫敏組件詳解

    這篇文章主要介紹了Java的logback自定義日志脫敏組件詳解,一個(gè)項(xiàng)目在書寫了很多打印日志的代碼,但是后面有了脫敏需求,如果我們?nèi)ナ謩?dòng)改動(dòng)代碼,會(huì)花費(fèi)大量時(shí)間,如果引入本組件,完成配置即可輕松完成脫敏,需要的朋友可以參考下
    2023-11-11
  • 解析JDK14中的java tools簡介

    解析JDK14中的java tools簡介

    這篇文章主要介紹了JDK14中的java tools簡介,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 如何使用IntelliJ IDEA搭建MyBatis-Plus框架并連接MySQL數(shù)據(jù)庫

    如何使用IntelliJ IDEA搭建MyBatis-Plus框架并連接MySQL數(shù)據(jù)庫

    這篇文章主要介紹了如何使用IntelliJ IDEA搭建MyBatis-Plus框架并連接MySQL數(shù)據(jù)庫,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11
  • java實(shí)現(xiàn)24點(diǎn)紙牌游戲

    java實(shí)現(xiàn)24點(diǎn)紙牌游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)24點(diǎn)紙牌游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03

最新評(píng)論

那曲县| 蓝田县| 宁河县| 宝兴县| 南木林县| 昌黎县| 册亨县| 昆山市| 梓潼县| 香河县| 沁源县| 邹平县| 上饶县| 重庆市| 砚山县| 方城县| 桐乡市| 泗水县| 扎囊县| 濮阳县| 隆尧县| 岐山县| 台州市| 汝阳县| 科尔| 遂溪县| 磴口县| 博客| 科尔| 伊金霍洛旗| 万盛区| 安图县| 黑水县| 嘉兴市| 铜川市| 裕民县| 萝北县| 清丰县| 五莲县| 松阳县| 将乐县|