springmvc+quartz實現定時任務;
1.pom.xml中添加依賴
1)springmvc依賴省略。。
2)quartz依賴
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.0</version> </dependency>
2. 代碼實現
1)systemJob實體類
省略 geter and seter
2.) service 類
3.)任務調度類
package com.meta.wx.quartz; import com.meta.wx.beans.SystemJob; import com.meta.wx.utils.DateUtil; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashSet; /** * 定時任務 * @author Administrator * CronTrigger的作業 (Trigger的另一個分支)比較強大 * 基於日歷的作業調度器 (如在每月的1號執行或每周一調用等) * 而不像SimpleTrigger那樣精確指定間隔時間,比SimpleTrigger更常用。 * Cront 表達式來設置調度的頻率 * 秒 分 時 日 月 周 年 順序設置 * * Scheduler 的主要函數 * Date scheduleJob(JobDetail jobDetail,Trigger trigger) 綁定JobDetail和Trigger 返回最近一次要執行的時間 * void start() 啟動 * void standby()掛起執行(可用start()開啟) * void shutdown()關閉 */ @Service public class JobTask { private Logger log= LoggerFactory.getLogger(JobTask.class); @Autowired private SchedulerFactoryBean schedulerFactoryBean; /** * 啟動任務 * @throws SchedulerException */ public boolean startJob(SystemJob sjob) throws SchedulerException{ //創建Scheduler實例 Scheduler scheduler=schedulerFactoryBean.getScheduler(); //創建一個JobDetail實例,綁定所建的作業 Class clazz= null; try { clazz = Class.forName(sjob.getClasspath()); } catch (ClassNotFoundException e) { e.printStackTrace(); } JobDetail jobDetail=JobBuilder.newJob(clazz).build(); // 創建一個Trigger; TriggerKey triggerKey=TriggerKey.triggerKey(sjob.getId(),Scheduler.DEFAULT_GROUP); CronTrigger trigger =(CronTrigger)TriggerBuilder.newTrigger() .withIdentity(triggerKey) .withSchedule( //1.2018年內每天10點15分出發一次 //可通過cront表達式在線生成 http://cron.qqe2.com/ CronScheduleBuilder.cronSchedule(sjob.getCron())//參數為cront表達式(秒 分 時 日 月 周 年) ) .build(); scheduler.scheduleJob(jobDetail,trigger);//綁定與觸發器 //啟動任務 if(!scheduler.isShutdown()){ scheduler.start(); log.info("---任務["+triggerKey.getName()+"] 啟動成功。。。"); return true; }else{ log.info("---任務["+triggerKey.getName()+"] 已啟動,無需再次啟動。。。"); } return false; } /** * 修改任務 * @param sjob * @return * @throws SchedulerException */ public boolean updateJob(SystemJob sjob) { //創建Scheduler實例 Scheduler scheduler=schedulerFactoryBean.getScheduler(); String createTime = DateUtil.getCurDate(); try { Class clazz =null; try { clazz = Class.forName(sjob.getClasspath()); } catch (ClassNotFoundException e) { e.printStackTrace(); } //創建一個JobDetail實例,綁定所建的作業(將該實例與HelloJobClass綁定) JobDetail jobDetail=JobBuilder.newJob(clazz).build(); // 創建一個Trigger; TriggerKey triggerKey=TriggerKey.triggerKey(sjob.getId(),Scheduler.DEFAULT_GROUP); if (scheduler.checkExists(triggerKey)){ return false; } JobKey jobKey=JobKey.jobKey(sjob.getId(),Scheduler.DEFAULT_GROUP); CronScheduleBuilder scheduleBuilder=CronScheduleBuilder.cronSchedule(sjob.getCron()) .withMisfireHandlingInstructionDoNothing(); CronTrigger trigger=TriggerBuilder.newTrigger().withIdentity(triggerKey) .withDescription(createTime).withSchedule(scheduleBuilder).build(); JobDetail jobDetail1=scheduler.getJobDetail(jobKey); HashSet<Trigger> triggerSet=new HashSet<>(); triggerSet.add(trigger); scheduler.scheduleJob(jobDetail,triggerSet,true); log.info("---任務[{}]更新成功---",triggerKey.getName()); return true; } catch (SchedulerException e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } } /** * 刪除 * @param job * @return */ public boolean remove(SystemJob job){ Scheduler scheduler=schedulerFactoryBean.getScheduler(); TriggerKey triggerKey=TriggerKey.triggerKey(job.getId(),Scheduler.DEFAULT_GROUP); try { if (checkJob(job)){ scheduler.pauseTrigger(triggerKey); scheduler.unscheduleJob(triggerKey); log.info("---任務[{}]刪除成功!",triggerKey.getName()); return true; } } catch (SchedulerException e) { e.printStackTrace(); } return false; } /** * true 存在 false 不存在 * @param job * @return */ public boolean checkJob(SystemJob job){ Scheduler scheduler=schedulerFactoryBean.getScheduler(); //觸發器 TriggerKey triggerKey=TriggerKey.triggerKey(job.getId(),Scheduler.DEFAULT_GROUP); try { if(scheduler.checkExists(triggerKey)){ return true; } } catch (SchedulerException e) { e.printStackTrace(); } return false; } }
4.)任務啟動線程類
package com.meta.wx.model; import com.meta.wx.beans.SystemJob; import com.meta.wx.quartz.JobTask; import com.meta.wx.service.JobService; import com.meta.wx.utils.SpringUtil; import org.quartz.Job; import org.quartz.SchedulerException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import javax.annotation.Resource; import java.util.List; /** * Created by Administrator on 2019/3/28. * 啟動數據庫中已經設定為啟動狀態(status:true)的任務,項目啟動時init */ @Configuration public class JobTreadModel extends Thread{ private Logger log= LoggerFactory.getLogger(JobTreadModel.class); @Resource private JobService jobService; @Override public void run() { try { Thread.sleep(1000); log.info("---啟動任務線程----"); JobTask jobTask = SpringUtil.getBean("jobTask"); List<SystemJob> jobList = jobService.startJob(); //開啟任務 jobList.forEach(jobs -> { log.info("---任務[{}] 系統 init---開始啟動 ", jobs.getId()); try { jobTask.startJob(jobs); } catch (SchedulerException e) { e.printStackTrace(); } }); if (jobList.size() == 0) { log.info("---數據庫暫無啟動的任務---------"); } else { log.info("---任務啟動完畢---------"); } } catch (InterruptedException e) { e.printStackTrace(); } } }
5)使用spring的ApplicationListener監聽待加載完畢時啟動任務
package com.meta.wx.model; import org.apache.log4j.Logger; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; /** * Created by Administrator on 2019/3/28. * 通過監聽,開辟線程,執行定時任務 當然 也可以執行其他 */ @Component public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> { public Logger log=Logger.getLogger(MyApplicationListener.class); /** * bean加載完之后執行 * @param event */ @Override public void onApplicationEvent(ContextRefreshedEvent event) { System.out.println("-------------bean初始化完畢-------------"); /** * 系統兩種容器:root application context 和項目名-servlet context ; * 下面代碼防止執行兩次 */ if(event.getApplicationContext().getParent() == null) { JobTreadModel myThread = (JobTreadModel) event.getApplicationContext().getBean( "jobTreadModel"); myThread.start(); } } }
6)配置spring的Application_mvc.xml
<!-- quartz 定時任務配置--> <bean id="jobFactory" class="com.meta.wx.quartz.MyJobFactory"></bean> <bean name="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="jobFactory" ref="jobFactory"></property> </bean>