定時任務顧名思義到什么時間執行什么操作,在我現在寫的公司項目中,有一個帖子的下架和發布時用到了定時任務,
可以指定它的發布時間和下架時間,到點發布或下架。
Quartz特點
強大的調度功能,例如支持豐富多樣的調度方法,可以滿足各種常規及特殊需求;
靈活的應用方式,例如支持任務和調度的多種組合方式,支持調度數據的多種存儲方式;
分布式和集群能力,Terracotta 收購后在原來功能基礎上作了進一步提升。
另外,作為 Spring 默認的調度框架,Quartz 很容易與 Spring 集成實現靈活可配置的調度功能。
quartz調度核心元素:
- Scheduler:任務調度器,是實際執行任務調度的控制器。在spring中通過SchedulerFactoryBean封裝起來。
- Trigger:觸發器,用於定義任務調度的時間規則,有SimpleTrigger,CronTrigger,DateIntervalTrigger和NthIncludedDayTrigger,其中CronTrigger用的比較多,本文主要介紹這種方式。CronTrigger在spring中封裝在CronTriggerFactoryBean中。
- Calendar:它是一些日歷特定時間點的集合。一個trigger可以包含多個Calendar,以便排除或包含某些時間點。
- JobDetail:用來描述Job實現類及其它相關的靜態信息,如Job名字、關聯監聽器等信息。在spring中有JobDetailFactoryBean和 MethodInvokingJobDetailFactoryBean兩種實現,如果任務調度只需要執行某個類的某個方法,就可以通過MethodInvokingJobDetailFactoryBean來調用。
- Job:是一個接口,只有一個方法void execute(JobExecutionContext context),開發者實現該接口定義運行任務,JobExecutionContext類提供了調度上下文的各種信息。Job運行時的信息保存在JobDataMap實例中。實現Job接口的任務,默認是無狀態的,若要將Job設置成有狀態的,在quartz中是給實現的Job添加@DisallowConcurrentExecution注解(以前是實現StatefulJob接口,現在已被Deprecated),在與spring結合中可以在spring配置文件的job detail中配置concurrent參數。
Cron表達式
代碼實現:
(一)依賴
<!-- Quartz坐標 --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> <!-- Scheduled坐標 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <!-- spring-tx坐標 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency>
(二)QuartzConfig
import org.quartz.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class QuartzConfig { @Bean public JobDetail printTimeJobDetail(){ return JobBuilder.newJob(DateTimeJob.class)//PrintTimeJob我們的業務類 .withIdentity("DateTimeJob")//可以給該JobDetail起一個id //每個JobDetail內都有一個Map,包含了關聯到這個Job的數據,在Job類中可以通過context獲取 .usingJobData("msg", "Hello Quartz")//關聯鍵值對 .storeDurably()//即使沒有Trigger關聯時,也不需要刪除該JobDetail .build(); } @Bean public Trigger printTimeJobTrigger() { CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?"); return TriggerBuilder.newTrigger() .forJob(printTimeJobDetail())//關聯上述的JobDetail .withIdentity("quartzTaskService")//給Trigger起個名字 .withSchedule(cronScheduleBuilder) .build(); } }
(三)DateTimeJob
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.quartz.QuartzJobBean; import woke.cloud.official.mapper.SocialPostHelpMapper; import java.text.SimpleDateFormat; /** * Quartz的配置類 */ public class DateTimeJob extends QuartzJobBean { @Autowired private SocialPostHelpMapper socialPostHelpMapper; private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { //修改發布時間 socialPostHelpMapper.updateReatesTime(); //修改下架時間 socialPostHelpMapper.updateOffSheltTime(); } }
(四)xml
<!--發布--> <update id="updateReatesTime"> UPDATE woke_cloud_social.social_post_help SET release_status = 2 WHERE <!--判斷當前時間大於發布時間並且狀態是待發布,如果大於改發布狀態為2--> NOW() > release_time AND release_status = 1 </update>
<!--下架--> <update id="updateOffSheltTime"> UPDATE woke_cloud_social.social_post_help SET status = 1 WHERE <!--判斷當前時間大於下架時間並且狀態是已發布,如果大於下架該條帖子,狀態改1--> NOW() > off_shelf_time AND release_status = 2 </update>