SpringBoot 集成 quartz @Autowired为null

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot 集成 quartz @Autowired为null相关的知识,希望对你有一定的参考价值。

参考技术A 项目中用的quartz执行定时任务,但是执行的Job里,@Autowired为null。原因是quartz自己管理的Job对象,没有被SpringBoot管理,解决办法就是托管给Spring Boot管理。

没经过多方查找资料,找的了一个简单的解决方法。如下

添加Pom依赖

定义执行的job

SpringBoot2.6.3集成quartz

quartz使用

quartz启动需要数据库有很多表的支持,这些表的建表脚本可以通过如下方式找到

如何找到quartz的数据库脚本
在这里下载,需要注意的是下载2.2.3这个版本,不知道为什么高版本的反而没有。

集成Springboot

代码
yml配置

spring:
  application:
    name: demo-excel
  datasource:
    url: jdbc:mysql://rm-xxx.mysql.rds.aliyuncs.com:3306/quartz_demo?zeroDateTimeBehavior=convertToNull
    password: quartz_demo
    username: quartz_demo
    driver-class-name: com.mysql.cj.jdbc.Driver
    name: datasource1
  quartz:
    # quartz任务存储类型:jdbc或memory
    job-store-type: jdbc
    # 关闭时等待任务完成
    wait-for-jobs-to-complete-on-shutdown: true
    # 可以覆盖已有的任务
    overwrite-existing-jobs: true
    properties:
      org:
        quartz:
          scheduler:
            # 调度器实例名称
            instanceName: scheduler
            # 调度器实例ID自动生成
            instanceId: AUTO
          jobStore:
            class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            # quartz相关表前缀
            tablePrefix: QRTZ_
            useProperties: false
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            # 设置并发线程数量
            threadCount: 10
            # 指定线程优先级
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true
server:
  port: 8190
mybatis-plus:
  mapper-locations: classpath*:/mapperxml/*.xml

实现一个最简单的任务,该任务输出1111

@Component
public class TestJob extends QuartzJobBean 

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext)
            throws JobExecutionException 
        // 任务的具体逻辑
        System.out.println(1111);
    

配置这个任务的执行计划

@Configuration
public class QuartzConfig 

    @Bean
    public JobDetail jobDetail() 
        JobDetail jobDetail = JobBuilder.newJob(TestJob.class)
                .withIdentity("test", "test")
                .storeDurably()
                .build();
        return jobDetail;
    

    @Bean
    public Trigger trigger() 
        Trigger trigger = TriggerBuilder.newTrigger()
                .forJob(jobDetail())
                .withIdentity("test", "test")
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?"))
                .build();
        return trigger;
    

启动任务会看到控制台每秒钟打印一次1111

进阶

上诉任务是配置在代码中,执行策略为每秒钟打印一次,试想一个场景,我们这个任务的执行策略随时会变化,不可能每次一变化就去改代码。那么有没有办法把任务配置数据库中呢,再进一步,我们能不能做一个定时任务的维护页面,可以对定时任务的执行策略修改,同时可以通过页面删除定时任务,新增定时任务应该怎么做呢?

先定义一张存储定时任务的表

-- auto-generated definition
create table sys_job
(
    id              bigint                  not null primary key,
    job_name        varchar(64)             not null comment '任务名称',
    job_group       varchar(64)             not null comment '任务组名',
    method_name     varchar(500)            null comment '任务方法',
    method_params   varchar(50)             null comment '方法参数',
    cron_expression varchar(255)            null comment 'cron执行表达式',
    misfire_policy  varchar(20) default '3' null comment '计划执行错误策略(1立即执行 2执行一次 3放弃执行)',
    concurrent      char        default '1' null comment '是否并发执行(0允许 1禁止)',
    status          char        default '0' null comment '状态(0正常 1暂停)',
    create_by       varchar(64)             null comment '创建者',
    create_time     datetime                null comment '创建时间',
    update_by       varchar(64)             null comment '更新者',
    update_time     datetime                null comment '更新时间',
    remark          varchar(500)            null comment '备注信息'
)
    comment '定时任务调度表';

插入一条数据

INSERT INTO quartz_demo.sys_job (id, job_name, job_group, method_name, method_params, cron_expression, misfire_policy, concurrent, status, create_by, create_time, update_by, update_time, remark) VALUES (1, 'testJob2', 'test2', 'exec', null, '* * * * * ?', '2', '1', '0', null, null, null, null, null);

同时定义一张执行结果记录表

-- auto-generated definition
create table sys_job_log
(
    job_log_id     int auto_increment comment '任务日志ID'
        primary key,
    job_name       varchar(64)      not null comment '任务名称',
    job_group      varchar(64)      not null comment '任务组名',
    method_name    varchar(500)     null comment '任务方法',
    method_params  varchar(50)      null comment '方法参数',
    job_message    varchar(500)     null comment '日志信息',
    status         char default '0' null comment '执行状态(0正常 1失败)',
    exception_info varchar(2000)    null comment '异常信息',
    create_time    datetime         null comment '创建时间'
)
    comment '定时任务调度日志表';

项目启动时读取这张表里的数据放到quartz中执行
由于代码太多了,这边就不列出来代码了,demo已经上传到GitHub,项目基于springboot、mybatisplus。启动加载任务的代码在com.bxoon.service.impl.SysJobServiceImpl

以上是关于SpringBoot 集成 quartz @Autowired为null的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot 2.1.1.RELEASE 集成quartz

SpringBoot2.6.3集成quartz

SpringBoot2.6.3集成quartz

SpringBoot集成Quartz动态定时任务

SpringBoot2.6.3集成quartz

springboot集成quartz实现任务调度