Maison  >  Article  >  Java  >  Comment intégrer Quartz avec SpringBoot

Comment intégrer Quartz avec SpringBoot

PHPz
PHPzavant
2023-05-10 18:46:06901parcourir

Dépendance de base

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
    <version>2.5.2</version>
</dependency>

Quartz est un cadre de tâches planifiées couramment utilisé dans les projets d'application unique. Les tâches planifiées peuvent être principalement divisées en :

  • Tâches en mémoire : Généralement définies et stockées à l'intérieur du projet, si le projet est redémarré, si la tâche n'est pas automatiquement exécutée, elle ne sera pas redémarrée.

  • Tâches persistantes : stockez les caractéristiques de la tâche dans la base de données. Une fois le projet redémarré, la tâche en cours d'exécution peut être relue et poursuivie.

cron expression

corn est utilisée pour contrôler l'heure à laquelle une tâche est déclenchée. corn是用来控制任务触发的时刻。

我列举一些常用的:

  • 每秒钟触发

"* * * * * *":
  • 每隔5秒执行一次

*/5 * * * * ?
  • 每分钟触发

"0 * * * * ?"
  • 每一小时触发

"0 * * * * ?"
  • 每天10点触发一次

"0 0 10 * * ?"
  • 每天0点触发一次

"0 0 0 * * ?"

通用

需要在启动类上加上@EnableScheduling注解。

内存任务

工程启动时就在执行的任务

直接定义一个执行任务,例如:

每秒都输出测试

@Service
public class ScheduleTest {

    @Scheduled(cron = "0/1 * * * * *")
    public void test() {
        System.out.println("测试");
    }
}

启动类:

@SpringBootApplication
@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

启动后看控制台中就会输出相应的内容。

手动控制某个任务

这里需要我们自己定义任务。

定义任务

通过实现Job接口,即可定义一个任务,并且我们可以手动去控制这个任务的开启。

public class SimpleJob implements Job {
    @Override
    public void execute(JobExecutionContext context) {
        System.out.println("自定义任务");
    }
}

借助Web-Controller去开启该任务

导入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.3.6.RELEASE</version>
</dependency>

编写Controller,这是一个固定的写法。

  • 指定任务: JobBuilder.newJob(任务.class) .withIdentity(任务名, 任务组).build();

  • 指定cron表达式,创建Trigger:

    • CronScheduleBuilder.cronSchedule(cron表达式);

    • TriggerBuilder.newTrigger().withIdentity(启动器的名字, 启动器的分组) .withSchedule(cron).build();

  • 调用任务:scheduler.scheduleJob(任务类型对象, 启动器对象)

/**
 * @ClassName
 * @Description
 * @Author:chengyunlai
 * @Date
 * @Version 1.0
 **/
@RestController
public class DynamicScheduleController {

    @Autowired
    private Scheduler scheduler;

    @GetMapping("/addSchedule")
    public String addSchedule() throws SchedulerException {
        int random = ThreadLocalRandom.current().nextInt(1000);
        // 1. 创建JobDetail,指定定时任务实现类的类型
        JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class)
                .withIdentity("test-schedule" + random, "test-group").build();
        // 2. 创建Trigger,并指定每3秒执行一次
        CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule("0/3 * * * * ?");

        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("test-trigger" + random, "test-trigger-group")
                .withSchedule(cron).build();

        // 3. 调度任务
        scheduler.scheduleJob(jobDetail, trigger);
        return "success";
    }

通过浏览器输入项目的地址,一般默认是localhost:8080/addSchedule,输入后即可看到控制台输出了任务执行的输出内容。

持久化

如果工程重启了,上面的SimpleJob这个定时任务并不会重新启动。解决的办法就是将任务持久化,Quartz提供了解决方案,SpringBoot简化了这个操作。我们只需要配置好:数据库、数据源、操作数据库的JDBC即可。

依赖:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.8</version>
</dependency>
  • 使用mysql数据库:导入它的驱动,mysql-connector-java。

  • 使用Druid作为我们的数据源:druid。

  • 使用spring-jdbc,帮助我们自动将任务信息存入到数据库中。

配置

# 设置将定时任务的信息保存到数据库
spring.quartz.job-store-type=jdbc

# 每次应用启动的时候都初始化数据库表结构
# 如果 spring.quartz.jdbc.initialize-schema 设置为 always 的话有个问题:每次重启应用的时候,跟 Quartz 相关的表会被删除重建!
# 所以为了避免表被重复创建,我们可以提前创建表,然后将其指定为never
spring.quartz.jdbc.initialize-schema=never

# 数据库配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/scheduled?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root

Quartz为我们准备了sql数据表

官网:Downloads (quartz-scheduler.org)

以我:quartz-2.3.0-SNAPSHOT为例子:

下载源码后,找到jdbcjobstore这个目录:

quartz-2.3.0-SNAPSHOTsrcorgquartzimpljdbcjobstore

然后会有一系列的sql文件,找到和你数据库匹配的那个sql文件即可,我用的是mysql。

Comment intégrer Quartz avec SpringBoot

执行SQL文件建表,我的数据库名是:scheduled,各位从我的url中应该也能看出来。

建表完成后,所有配置工作结束了,启动程序,重新在浏览器中输入:localhost:8080/addSchedule,然后刷新一下数据库,就会发现任务被持久化了,此时重启工程后,该任务依旧会自动执行。

暂停任务和删除任务

我们在手动开启该任务的时候会指定:

  • 任务的名称和组

JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class) .withIdentity(任务名,任务组).build();

在暂停和恢复任务时,就需要用JobKey.jobKey(任务名,任务组),得到一个JobKey,然后使用scheduler.pauseJob(jobkey)即可暂停任务;scheduler.resumeJob(jobKey)恢复任务。

  • 删除任务的时候需要将任务和Trigger都删除,而在上面我们可以拿到这个jobkey表示任务,我们也需要拿到trigger,同样的我们也定义过启动器的名字和分组。

`TriggerBuilder.newTrigger().withIdentity(启动器的名字, 启动器的分组) .withSchedule(cron).build();`

TriggerKey.triggerKey((启动器的名字, 启动器的分组);也可以拿到trigger

J'en liste quelques-uns couramment utilisés : 🎜🎜🎜🎜Déclencher toutes les secondes🎜🎜🎜
// 暂停
@GetMapping("/pauseSchedule")
public String pauseSchedule(String jobName, String jobGroup) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
    // 获取定时任务
    JobDetail jobDetail = scheduler.getJobDetail(jobKey);
    if (jobDetail == null) {
        return "error";
    }
    scheduler.pauseJob(jobKey);
    return "success";
}

// 恢复
@GetMapping("/remuseSchedule")
public String remuseSchedule(String jobName, String jobGroup) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
    // 获取定时任务
    JobDetail jobDetail = scheduler.getJobDetail(jobKey);
    if (jobDetail == null) {
        return "error";
    }
    scheduler.resumeJob(jobKey);
    return "success";
}

// 删除定时任务
@GetMapping("/removeSchedule")
public String removeSchedule(String jobName, String jobGroup, String triggerName, String triggerGroup) throws SchedulerException {
    TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
    JobKey jobKey = JobKey.jobKey(jobName, jobGroup);

    Trigger trigger = scheduler.getTrigger(triggerKey);
    if (trigger == null) {
        return "error";
    }
    // 停止触发器
    scheduler.pauseTrigger(triggerKey);
    // 移除触发器
    scheduler.unscheduleJob(triggerKey);
    // 删除任务
    scheduler.deleteJob(jobKey);
    return "success";
}
🎜🎜🎜Exécuter toutes les 5 secondes🎜🎜🎜rrreee🎜🎜🎜Déclencher toutes les minutes🎜🎜🎜rrreee 🎜🎜 🎜Déclenchement toutes les heures 🎜🎜🎜 rrreee🎜🎜🎜Déclenché une fois par jour à 10 heures🎜🎜🎜rrreee🎜🎜🎜Déclenché une fois par jour à 0 heures🎜🎜🎜rrreee🎜Général🎜🎜Vous devez ajouter le @EnableScheduling annotation sur la classe de démarrage. 🎜🎜Tâche mémoire🎜

Tâche exécutée au démarrage du projet

🎜Définissez directement une tâche d'exécution, par exemple : 🎜🎜Sortie test toutes les secondes🎜rrreee🎜Classe de démarrage : 🎜 rrreee🎜Après le démarrage, le contenu correspondant sera affiché dans la console. 🎜

Contrôler manuellement une tâche

🎜Ici, nous devons définir la tâche nous-mêmes. 🎜

Définir la tâche

🎜En implémentant l'interface Job, nous pouvons définir une tâche, et nous pouvons contrôler manuellement l'ouverture de cette tâche. 🎜rrreee

Utilisez Web-Controller pour démarrer cette tâche

🎜Importer les dépendances : 🎜rrreee🎜Writing Controller, c'est une manière fixe d'écrire. 🎜🎜🎜🎜Spécifiez la tâche : JobBuilder.newJob(task.class) .withIdentity(task name, task group).build();🎜🎜🎜🎜Spécifiez l'expression cron et créez un déclencheur : 🎜🎜
    🎜🎜CronScheduleBuilder.cronSchedule(cron expression);🎜🎜🎜🎜TriggerBuilder.newTrigger().withIdentity(le nom du launcher, Regroupement de starters) .withSchedule(cron).build();🎜🎜🎜🎜🎜Appel de tâche : scheduler.scheduleJob (objet type de tâche, objet starter)🎜🎜🎜rrreee 🎜Entrez l'adresse du projet via le navigateur. La valeur par défaut est généralement localhost:8080/addSchedule. Après avoir saisi, vous pouvez voir la console afficher le contenu de sortie de l'exécution de la tâche. 🎜🎜Persistance🎜🎜Si le projet est redémarré, la tâche planifiée SimpleJob ci-dessus ne sera pas redémarrée. La solution est de conserver la tâche. Quartz fournit une solution SpringBoot simplifie cette opération. Il nous suffit de configurer : la base de données, la source de données et JDBC pour faire fonctionner la base de données. 🎜🎜Dépendances : 🎜rrreee🎜🎜🎜Utiliser la base de données mysql : importer son pilote, mysql-connector-java. 🎜🎜🎜🎜Utiliser Druid comme source de données : Druid. 🎜🎜🎜🎜Utilisez spring-jdbc pour nous aider à stocker automatiquement les informations sur les tâches dans la base de données. 🎜🎜🎜

    Configuration

    rrreee

    Quartz a préparé une table de données SQL pour nous

    🎜Site officiel : Téléchargements (quartz-scheduler.org)🎜🎜Utilisation : quartz-2.3.0-SNAPSHOT Par exemple : 🎜🎜Après avoir téléchargé le code source, recherchez le répertoire jdbcjobstore : 🎜🎜quartz-2.3.0-SNAPSHOTsrcorgquartzimpljdbcjobstore🎜🎜 Ensuite, il y aura une série de sql code>, trouvez simplement le fichier sql qui correspond à votre base de données. J'utilise mysql. 🎜🎜<img src="https://img.php.cn/upload/article/000/000/164/168371556976615.png" alt="Comment SpringBoot intègre Quartz">🎜🎜Exécutez le fichier SQL pour créer la table, I Le nom de la base de données est : <code>programmé, vous devriez pouvoir le voir depuis mon URL. 🎜🎜Une fois la création de la table terminée, tout le travail de configuration est terminé. Démarrez le programme et saisissez à nouveau : localhost:8080/addSchedule dans le navigateur, puis actualisez la base de données et vous constaterez que la tâche est terminée. est persisté. Après avoir redémarré le projet à ce moment-là, la tâche sera toujours exécutée automatiquement. 🎜🎜Pause des tâches et suppression de tâches🎜🎜Lorsque nous ouvrirons manuellement la tâche, nous préciserons : 🎜🎜🎜🎜Le nom et le groupe de la tâche🎜🎜🎜rrreee🎜Lors de la pause et de la reprise d'une tâche, vous devez utiliser JobKey.jobKey (nom de la tâche, groupe de tâches), obtenez une JobKey, puis utilisez scheduler.pauseJob(jobkey) pour suspendre la tâche  ; Scheduler.resumeJob( jobKey)Reprendre la tâche. 🎜🎜🎜🎜Lors de la suppression d'une tâche, vous devez supprimer à la fois la tâche et le déclencheur. Ci-dessus, nous pouvons obtenir la jobkey pour représenter la tâche. Nous devons également obtenir le déclencheur. a également défini le nom et le regroupement du lanceur. 🎜🎜🎜rrreee🎜TriggerKey.triggerKey((nom du lanceur, groupe de lanceurs);Vous pouvez également obtenir trigger pour représenter le lanceur.🎜
    • 通过以下顺序完整删除任务

      • scheduler.deleteJob(jobKey);

      • scheduler.unscheduleJob(triggerKey);

      • scheduler.pauseTrigger(triggerKey);

      • // 停止触发器

      • // 移除触发器

      • // 删除任务

    // 暂停
    @GetMapping("/pauseSchedule")
    public String pauseSchedule(String jobName, String jobGroup) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        // 获取定时任务
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail == null) {
            return "error";
        }
        scheduler.pauseJob(jobKey);
        return "success";
    }
    
    // 恢复
    @GetMapping("/remuseSchedule")
    public String remuseSchedule(String jobName, String jobGroup) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        // 获取定时任务
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail == null) {
            return "error";
        }
        scheduler.resumeJob(jobKey);
        return "success";
    }
    
    // 删除定时任务
    @GetMapping("/removeSchedule")
    public String removeSchedule(String jobName, String jobGroup, String triggerName, String triggerGroup) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
    
        Trigger trigger = scheduler.getTrigger(triggerKey);
        if (trigger == null) {
            return "error";
        }
        // 停止触发器
        scheduler.pauseTrigger(triggerKey);
        // 移除触发器
        scheduler.unscheduleJob(triggerKey);
        // 删除任务
        scheduler.deleteJob(jobKey);
        return "success";
    }

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer