昨天看定時器,被Quartz定時器框架困擾到如今,覺得是調用的時候出了問題,覺得是我不知道怎麼調用而後出的問題,結果是少了jar包。哎,這個問題真的是,告訴咱們之後導入一個框架的jar包時,必定要導全,不要只導核心包,由於核心包可能依賴其餘包。java
定時任務不執行緣由:沒有導入除quartz-2.3.0-SHAPSHOT.jar之外的包。web
解決方法,把其他包都導入。框架
這個問題真的是!!!!!真是個值得記憶的教訓。如今來講說定時器吧!ide
我在理解定時器的時候,提出了這些問題!ui
首先,jdk自帶Timer,TimerTask類,能夠實現定時任務,爲何還須要其餘定時器框架呢?spa
用java自帶的類來作定時任務時,只需寫一個類,讓這個類extendsTimerTask,而後重寫它的Run()方法。code
而後,若是把定時器放在監聽器裏的話,直接在監聽器的某個方法中執行Timer的schedule(task,...)方法。orm
咱們能夠發現,xml
schedule(task, 0, PERIOD*PERIODTIME);方法實現的定時種類很少。它不能控制一些複雜的定時任務。
因此這就是爲何要使用其餘定時器框架的緣由吧,由於不能知足複雜的任務需求。對象
那常見的定時器框架有哪些呢?
java定時器,Spring定時器,Quartz定時器。
我暫時只用過java自帶的定時器和Quartz定時器,由於Quartz定時器已經夠強大了,我以爲了解Spring定時器也就不必了。
那Quartz定時器框架是怎麼用的呢?
首先咱們要理解Quartz的幾個核心概念。
而後咱們要引入咱們須要的jar包,注意一個都不能少,否則會引起一系列問題,前面已經截圖過。
最後咱們進入代碼部分。
咱們要先建一個job類,它是任務的核心,即這個定時任務究竟要作什麼,就是作的內容。這個類須要implements該框架的Job類,而後實現它的execute()方法,方法的具體內容就是執行的這個任務,即任務的內容。
而後,咱們須要建立一個JobDetail。
JobDetail 表示一個具體的可執行的調度程序,Job 是這個可執行程調度程序所要執行的內容,另外 JobDetail 還包含了這個任務調度的方案和策略。最開始建立的job類就會在建立它時被用到。
接着呢,咱們須要建立一個觸發器,Trigger 。
Trigger 表明一個調度參數的配置,何時去調。它能夠配置定時任務中的定時。尤爲是cron表達式的配置,讓定時任務想怎麼定時就怎麼定時,配置能夠在http://cron.qqe2.com/中生成,方便快捷。
最後呢,咱們須要一個調度器,Scheduler。
Scheduler 表明一個調度容器,一個調度容器中能夠註冊多個 JobDetail 和 Trigger。當 Trigger 與 JobDetail 組合,就能夠被 Scheduler 容器調度了。剛剛建立的JobDetail和Trigger都需被它調度。
最後的最後,咱們只需在監聽器或者其餘地方直接調用剛剛寫好的方法便可,而後若是實在監聽器裏調用的話,程序一執行,定時任務就開始了。下面我粘一下個人代碼。
web.xml中的配置。
<listener> <listener-class>com.practice.mylistener.QuartzListener</listener-class> </listener>
QuartzListener類。
package com.practice.mylistener; import com.practice.tool.QuartzTimeManager; import com.practice.tool.QuertzTask; import com.practice.tool.job; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class QuartzListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent servletContextEvent) { System.out.println("quertztask監聽器啓動=============================="); QuartzTimeManager.addJob("myJob","group1","mytrigger","group1", job.class,"1-2 * * * * ?"); System.out.println("task excute=================================="); } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { } }
QuartzListener類
package com.practice.tool; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import java.util.Collection; public class QuartzTimeManager { private static SchedulerFactory schedulerFactory = new StdSchedulerFactory(); /** * @Description: 添加一個定時任務 * * @param jobName 任務名 * @param jobGroupName 任務組名 * @param triggerName 觸發器名 * @param triggerGroupName 觸發器組名 * @param jobClass 任務 * @param cron 時間設置,參考quartz說明文檔 */ public static void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String cron) { try { Scheduler sched = schedulerFactory.getScheduler(); // 任務名,任務組,任務執行類 JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build(); // 觸發器 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger(); // 觸發器名,觸發器組 triggerBuilder.withIdentity(triggerName, triggerGroupName); triggerBuilder.startNow(); // 觸發器時間設定 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); // 建立Trigger對象 CronTrigger trigger = (CronTrigger) triggerBuilder.build(); // 調度容器設置JobDetail和Trigger sched.scheduleJob(jobDetail, trigger); // 啓動 if (!sched.isShutdown()) { System.out.println("=================定quartz定時任務開始"); sched.start(); } } catch (SchedulerException e) { e.printStackTrace(); } } /** * @Description: 修改一個任務的觸發時間 * * @param jobName * @param jobGroupName * @param triggerName 觸發器名 * @param triggerGroupName 觸發器組名 * @param cron 時間設置,參考quartz說明文檔 */ public static void modifyJobTime(String jobName, String jobGroupName, String triggerName, String triggerGroupName, String cron) { try { Scheduler sched = schedulerFactory.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey); if (trigger == null) { return; } String oldTime = trigger.getCronExpression(); if (!oldTime.equalsIgnoreCase(cron)) { /** 方式一 :調用 rescheduleJob 開始 */ // 觸發器 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger(); // 觸發器名,觸發器組 triggerBuilder.withIdentity(triggerName, triggerGroupName); triggerBuilder.startNow(); // 觸發器時間設定 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); // 建立Trigger對象 trigger = (CronTrigger) triggerBuilder.build(); // 方式一 :修改一個任務的觸發時間 sched.rescheduleJob(triggerKey, trigger); /** 方式一 :調用 rescheduleJob 結束 */ /** 方式二:先刪除,而後在建立一個新的Job */ //JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName)); //Class<? extends Job> jobClass = jobDetail.getJobClass(); //removeJob(jobName, jobGroupName, triggerName, triggerGroupName); //addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron); /** 方式二 :先刪除,而後在建立一個新的Job */ } } catch (Exception e) { throw new RuntimeException(e); } } /** * @Description: 移除一個任務 * * @param jobName * @param jobGroupName * @param triggerName * @param triggerGroupName */ public static void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) { try { Scheduler sched = schedulerFactory.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); sched.pauseTrigger(triggerKey);// 中止觸發器 sched.unscheduleJob(triggerKey);// 移除觸發器 sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 刪除任務 } catch (Exception e) { throw new RuntimeException(e); } } /** * @Description:啓動全部定時任務 */ public static void startJobs() { try { Scheduler sched = schedulerFactory.getScheduler(); sched.start(); } catch (Exception e) { throw new RuntimeException(e); } } /** * @Description:關閉全部定時任務 */ public static void shutdownJobs() { try { Scheduler sched = schedulerFactory.getScheduler(); if (!sched.isShutdown()) { sched.shutdown(); } } catch (Exception e) { throw new RuntimeException(e); } } }
job類
package com.practice.tool; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.text.SimpleDateFormat; import java.util.Date; public class job implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); Date date=new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Time:"+sf.format(date)); System.out.println("Hello"); } }
運行結果:
最重要的一點,注意導入jar包要完整哦!其實定時器仍是挺簡單的對不對。