Spring Boot crea tareas de sincronización dinámica

Prefacio

Hace un tiempo, había una demanda de tareas de sincronización dinámica, el período de construcción era ajustado y no se introdujo en el proyecto Quartz.
En este punto, parece que solo se pueden considerar las tareas de sincronización proporcionadas por Spring Boot.

Investigación

Las tareas programadas en Spring Boot generalmente se @Scheduledanotan con anotaciones, y puede establecer la cronexpresión correspondiente o establecer el período de intervalo de ejecución.
El código de muestra es el siguiente:

@Scheduled(cron="0/5 * * * * ?")
    void testPlaceholder1() {
        System.out.println("Execute at " + System.currentTimeMillis());
    }

Sin embargo, el uso de anotaciones para marcar tareas cronometradas no puede satisfacer las necesidades de actualizaciones periódicas de tareas cronometradas.

rescate

Consulte datos y descubrió que puede usar la SchedulingConfigurerinterfaz de herencia para implementar tareas de sincronización dinámica.

@Slf4j
@Configuration
public class ImepStatusSchedulingConfig implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(
            ()->{
                // 业务逻辑
            },
            triggerContext -> {
                // 此处,cron表达式从数据库查询得到
                String cron = cronMapper.getCron();
                // 根据cron表达式,构建CronTrigger,计算下一次的执行时间
                CronTrigger trigger = new CronTrigger(cron);
                return trigger.nextExecutionTime(triggerContext);
            }
        );
    }
}

Se puede ver en el código que cada vez que se ejecuta una tarea programada, el siguiente punto de tiempo de ejecución se calculará dinámicamente.

cambio

Las expresiones cron son más complicadas (el proyecto lo mantienen varias personas) y los requisitos solo requieren soporte para ejecutar tareas en intervalos fijos de segundos.
Por tanto, ya CronTriggerno es adecuado y, por tanto, debe modificarse en consecuencia. Los cambios son los siguientes:

 // 出于篇幅,此处省略无关代码
    triggerContext -> {
        // 此处,duration可以从数据库查询得到
        int duration = 1;
        Date date = triggerContext.lastCompletionTime();
        if (date != null) {
            Date scheduled = triggerContext.lastScheduledExecutionTime();
            if (scheduled != null && date.before(scheduled)) {
                // Previous task apparently executed too early...
                // Let's simply use the last calculated execution time then,
                // in order to prevent accidental re-fires in the same second.
                date = scheduled;
            }
        } else {
            date = new Date();
        }
        date.setTime(date.getTime() + duration * 1000);
        return date;
    }

De esta manera, se realiza la tarea de temporización de establecer dinámicamente los segundos de intervalo.

Supongo que te gusta

Origin blog.csdn.net/a159357445566/article/details/108603666
Recomendado
Clasificación