Introdução ao Quartz e Uso de Expressões Cron para Agendamento de Tarefas em Java

Visão Geral do Quartz e Cenários de Aplicação

O Quartz é um framework de agendamento de tarefas de código aberto, desenvolvido em Java, que permite executar tarefas em horários específicos. Ele é utilizado para automatizar processos, como o cancelamento automático de pedidos não pagos após um tempo determinado.

Tipos de Gatilhos no Quartz

O Quartz oferece diferentes tipos de gatilhos para definir quando uma tarefa deve ser executada. Os mais comuns são o SimpleTrigger, para agendamentos simples baseados em intervalos, e o CronTrigger, que usa expressões cron para agendamentos complexos.

Opções de Armazenamento

O Quartz suporta armazenamento em memória (RAMJobStore) ou em banco de dados (JDBCJobStore). O armazenamento em memória é rápido mas perde dados ao reiniciar a aplicação, enquanto o armazenamento em banco de dados permite persistência e escalabilidade em clusters.

Entendendo as Expressões Cron

As expressões cron são usadas para definir horários de execução precioss. A tabela abaixo descreve os campos disponíveis:

Posição Significado Valores Válidos Caracteres Especiais
1 Segundos 0-59 , - * /
2 Minutos 0-59 , - * /
3 Horas 0-23 , - * /
4 Dia do Mês 1-31 , - * / ? L W
5 Mês 0-11 ou strings como JAN, FEB , - * /
6 Dia da Semana 1-7 ou strings como SUN, MON (1=Domingo) , - * / ? L #
7 Ano (opcional) 1970-2099 , - * /

Caracteres Especiais nas Expressões Cron

  • /: Define intervalos. Exemplo: "3/15" no campo de minutos significa iniciar no minuto 3 e repetir a cada 15 minutos.
  • ?: Usado nos campos de dia do mês e dia da semana para evitar conflitos. Exemplo: "0 0 4 15 * ?" executa às 4h do dia 15 de cada mês.
  • L: Representa o último dia. Exemplo: "0 15 10 ? * 6L" executa na última sexta-feira do mês às 10:15.
  • W: Dia útil mais próximo. Exemplo: "0 15 10 15W * ?" executa no dia útil mais próximo do dia 15.
  • #: Enésimo dia da semana. Exemplo: "0 15 10 ? * 6#3" executa na terceira sexta-feira do mês.

Configuração Inicial do Quartz com Maven

Para começar, adicione as dependências do Quartz ao seu projeto Maven:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.2.1</version>
</dependency>

Criando uma Classe de Tarefa

Defina uma classe que implemente a interface Job para conter a lógica da tarefa:

package com.example.quartz.task;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class TarefaExecucao implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("Executando a tarefa agendada.");
    }
}

Usando o SimpleTrigger

O SimpleTrigger é ideal para agendamentos baesados em intervalos fixos. O exemplo abaixo configura uma tarefa para ser executada 3 vezes, com intervalo de 6 segundos:

package com.example.quartz.example;
import com.example.quartz.task.TarefaExecucao;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

public class ExemploTriggerSimples {
    public static void main(String[] args) throws SchedulerException {
        SchedulerFactory fabrica = new StdSchedulerFactory();
        Scheduler agendador = fabrica.getScheduler();

        JobDetail detalheTarefa = JobBuilder.newJob(TarefaExecucao.class)
                .withIdentity("tarefa1", "grupo1")
                .build();

        Trigger gatilho = TriggerBuilder.newTrigger()
                .withIdentity("gatilho1", "grupo1")
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(3, 6))
                .build();

        agendador.scheduleJob(detalheTarefa, gatilho);
        agendador.start();
    }
}

Usando o CronTrigger

O CronTrigger permite agendamentos complexos usando expressões cron. Este exemplo executa uma tarefa a cada 3 segundos:

package com.example.quartz.example;
import com.example.quartz.task.TarefaExecucao;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

public class ExemploTriggerCron {
    public static void main(String[] args) throws SchedulerException {
        SchedulerFactory fabrica = new StdSchedulerFactory();
        Scheduler agendador = fabrica.getScheduler();

        JobDetail detalheTarefa = JobBuilder.newJob(TarefaExecucao.class)
                .withIdentity("tarefa2", "grupo2")
                .build();

        Trigger gatilho = TriggerBuilder.newTrigger()
                .withIdentity("gatilho2", "grupo2")
                .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))
                .build();

        agendador.scheduleJob(detalheTarefa, gatilho);
        agendador.start();
    }
}

Passando Parâmetros para Tarefas

Você pode transmitir dados para a tarefa usando o JobDataMap. Configure os parâmetros ao criar o detalhe da tarefa e acesse-os na classe da tarefa:

package com.example.quartz.example;
import com.example.quartz.task.TarefaExecucao;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

public class ExemploComParametros {
    public static void main(String[] args) throws SchedulerException {
        SchedulerFactory fabrica = new StdSchedulerFactory();
        Scheduler agendador = fabrica.getScheduler();

        JobDetail detalheTarefa = JobBuilder.newJob(TarefaExecucao.class)
                .withIdentity("tarefa3", "grupo3")
                .build();

        JobDataMap mapaDados = detalheTarefa.getJobDataMap();
        mapaDados.put("nome", "Ana");
        mapaDados.put("departamento", "TI");

        Trigger gatilho = TriggerBuilder.newTrigger()
                .withIdentity("gatilho3", "grupo3")
                .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))
                .build();

        agendador.scheduleJob(detalheTarefa, gatilho);
        agendador.start();
    }
}

Na classe da tarefa, recupere os parâmetros assim:

package com.example.quartz.task;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class TarefaExecucao implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap mapaDados = context.getJobDetail().getJobDataMap();
        String nome = mapaDados.getString("nome");
        String departamento = mapaDados.getString("departamento");
        System.out.println("Tarefa executada para " + nome + " do departamento " + departamento);
    }
}

Comparação entre Spring Task e Quartz

Spring Task: Integração simples com Spring, mas executa em modo single-thread e não suporta agendamentos persistentes.

Quartz: Suporta multi-threading e armazenamento persistente, ideal para tarefas críticas, mas requer configuração adicional com Spring.

Tags: Quartz cron Scheduler java Spring Task

Publicado em 6-8 20:04 por Thomas