1. 程式人生 > >spring 實現動態定時任務排程

spring 實現動態定時任務排程

概述

使用spring框架實現動態定時任務排程,可以不重啟專案,只修改cron表示式,即可變更任務執行週期。

spring xml配置:

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:task="http://www.springframework.org/schema/task"  
    xmlns:context
="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "
>
<context:component-scan base-package="com.chao.task.demo" /> <!-- Spring註解方式配置排程任務 --> <task:executor id="executor" pool-size="3"/> <task:scheduler id="scheduler" pool-size="3"/> <task:annotation-driven executor="executor" scheduler="scheduler"
/>
</beans>

下面介紹兩種方式實現:

方式一 (自定義service層,使用ScheduledFuture類實現):

特點:修改了任務時間後可以實時生效、任務需要手動呼叫啟動

@Service
public class NightAuditTaskServiceImpl implements NightAuditTaskService {
    private Logger logger = LoggerFactory.getLogger(NightAuditTaskServiceImpl.class);
    private ScheduledFuture<?> future;
    @Resource
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    //每次呼叫,會結束舊的任務,並重新開啟一個新定時任務
    @Override
    public synchronized void startTask(){
        if(future != null) {
            future.cancel(true);
        }
        future = threadPoolTaskScheduler.schedule(new Runnable() {
            @Override
            public void run() {
                logger.info("執行定時器xx");
                //處理業務邏輯
            }
        }, new CronTrigger("0/5 * * * *");//可宣告變數動態獲取cron表示式
    }
}

在專案啟動初始化時可以呼叫一次startTask(),啟動任務排程;當需要變更任務執行週期時,直接修改cron表示式,接著再呼叫 startTask()即可實時變更任務執行週期

方式二(使用註解@EnableScheduling 並實現SchedulingConfigurer介面)

特點:修改了任務時間並不會實時生效,需要在下一次任務執行之後才會生效

@Component
@EnableScheduling
public class DynamicCronTask implements SchedulingConfigurer{
    private Logger logger = LoggerFactory.getLogger(DynamicCronTask.class);

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(new Runnable() {
            @Override
            public void run() {
                logger.info("執行定時器xxx");
                // 任務邏輯
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                // 任務觸發,可宣告變數動態獲取cron表示式
                CronTrigger trigger = new CronTrigger("0/5 * * * * ?");
                Date nextExec = trigger.nextExecutionTime(triggerContext);
                return nextExec;
            }
        });
    }
}

專案啟動後掃啟動定時器,當需要變更任務執行週期時,直接修改cron表示式,會在下一次執行任務後才會更新任務執行週期