首页 > 其他分享 >Springcloud学习笔记67--springboot 整合 任务调度框架Quartz

Springcloud学习笔记67--springboot 整合 任务调度框架Quartz

时间:2024-05-17 11:44:13浏览次数:20  
标签:Quartz springboot Spring SchedulerFactoryBean springframework Job import org 任务调

1.背景

定时任务Job的作业类中无法注入Service等由Spring容器所管理的Bean。例如下面这种情况,TaskCronJobService就无法成功注入。

import java.util.Iterator;
 
import javax.annotation.Resource;
 
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;
 
import com.pengjunlee.task.bean.TaskCronJob;
import com.pengjunlee.task.service.TaskCronJobService;
 
/**
 * 定时任务的作业类,需实现Job接口
 * */
@Component
public class MyJob implements Job {
 
    @Resource
    private TaskCronJobService taskCronJobService;
 
    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("执行定时任务:MyJob.execute()..."
                + System.currentTimeMillis());
        Iterable<TaskCronJob> findAll = taskCronJobService.findAll();
        Iterator<TaskCronJob> iterator = findAll.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next().getJobClassName());
        }
    }
 
}

  定时任务Job对象的实例化过程是在Quartz中进行的,而TaskCronJobService Bean是由Spring容器管理的,Quartz根本就察觉不到TaskCronJobService Bean的存在,故而无法将TaskCronJobService Bean装配到Job对象中。

  知道了问题出现的原因,解决的办法也就显而易见了:如果能够将Job Bean也纳入到Spring容器的管理之中的话,Spring容器自然能够为Job Bean自动装配好所需的依赖。

  通过查看Spring官方文档得知,Spring与Quartz集成使用的是SchedulerFactoryBean这个类,其所需引入Maven依赖如下。

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>
        <!-- 该依赖必加,里面有sping对schedule的支持 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

以下是SchedulerFactoryBean类(spring-context-support 这个包)的部分关键代码。

package org.springframework.scheduling.quartz;
 
public class SchedulerFactoryBean extends SchedulerAccessor implements
        FactoryBean<Scheduler>, BeanNameAware, ApplicationContextAware,
        InitializingBean, DisposableBean, SmartLifecycle {
 
    @Override
    public void afterPropertiesSet() throws Exception {
        //---------------------------省略部分代码--------------------------
        // Get Scheduler instance from SchedulerFactory.
        try {
            this.scheduler = createScheduler(schedulerFactory, this.schedulerName);
            populateSchedulerContext();
 
            if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) {
                // Use AdaptableJobFactory as default for a local Scheduler, unless when
                // explicitly given a null value through the "jobFactory" bean property.
                this.jobFactory = new AdaptableJobFactory();
            }
            if (this.jobFactory != null) {
                if (this.jobFactory instanceof SchedulerContextAware) {
                    ((SchedulerContextAware) this.jobFactory).setSchedulerContext(this.scheduler.getContext());
                }
                this.scheduler.setJobFactory(this.jobFactory);
            }
        }
        //---------------------------省略部分代码--------------------------
    }
}

从以上代码可以看出:SchedulerFactoryBean 使用 AdaptableJobFactory 对Job对象进行实例化,如果未指定则SchedulerFactoryBean会自动创建一个,在这里如果我们能够将 SchedulerFactoryBean 的 jobFactory 指定为我们自定义的工厂实例的话,我们就能够有机会在Job实例化完成之后对其进行处理,并将其纳入到Spring容器的管理之中。

2. springboot整合quartz实践

例如下面这段代码,创建一个SchedulerFactoryBean 实例,并将其Job实例化的工厂指定为一个Spring容器中一个自定义的 TaskSchedulerFactory 实例。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 
@Configuration
public class QuartzConfig {
    @Autowired
    private QuartzJobFactory jobFactory;
 
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setJobFactory(jobFactory);
        return schedulerFactoryBean;
    }
 
    @Bean
    public Scheduler scheduler() {
        return schedulerFactoryBean().getScheduler();
    }
}

Quartz为我们提供了一个JobFactory接口,允许我们自定义实现创建Job的逻辑。

package org.quartz.spi;
public interface JobFactory {
    Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException;
}

AdaptableJobFactory 就是 Spring 为我们提供的一个该接口的实现类,提供了创建Job实例的基本方法。

自定义的工厂类 QuartzJobFactory 只需要继承 AdaptableJobFactory ,通过调用父类 AdaptableJobFactory 的方法来实现对Job的实例化,在Job实例化完以后,再调用自身方法为创建好的Job实例进行属性自动装配并将其纳入到Spring容器的管理之中。

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;
 
@Component
public class QuartzJobFactory extends AdaptableJobFactory
{
 
    // 需要使用这个BeanFactory对Qurartz创建好Job实例进行后续处理,属于Spring的技术范畴.
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;
 
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception
    {
        // 首先,调用父类的方法创建好Quartz所需的Job实例
        Object jobInstance = super.createJobInstance(bundle);
        // 然后,使用BeanFactory为创建好的Job实例进行属性自动装配并将其纳入到Spring容器的管理之中,属于Spring的技术范畴.
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

参考文献:

https://blog.csdn.net/pengjunlee/article/details/78965877 (SpringBoot重点详解--如何为Quartz的Job自动装配Spring容器Bean)

https://blog.csdn.net/qq_43419029/article/details/92659690

标签:Quartz,springboot,Spring,SchedulerFactoryBean,springframework,Job,import,org,任务调
From: https://www.cnblogs.com/luckyplj/p/18197538

相关文章

  • springboot集成@DS注解实现数据源切换(转载)
    springboot集成@DS注解实现数据源切换启用@DS实现数据源切换POM内添加核心jar包yml配置"核心"-使用@DS注解最后启用@DS实现数据源切换POM内添加核心jar包 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-start......
  • springboot怎么将List集合数据转成JSON数组
    SpringBoot默认使用Jackson框架将Java对象转换成JSON格式。要转换List集合数据为JSON数组,可以采用以下两种方法:1.使用@ResponseBody注解在SpringBoot中,可以使用@ResponseBody注解标注要返回的List集合数据,让Spring自动将其转换成JSON数组。例如:@GetMapping("/list")@Respo......
  • 关于SpringBoot项目使用Hutool工具进行json序列化时出现Null值过滤或者丢失的问题(转
    ##问题描述:SpringBoot项目中,一直使用的时Hutool的json转换工具,被强制要求不能使用fastJson工具;之前都没什么问题,突然有一次使用parseObj()进行json字符串转换json对象时,突然报错:Noserializerfoundforclasscn.hutool.json.JSONNullandnopropertiesdiscoveredtocreate......
  • 教你如何搞定springboot集成kafka
    本文分享自华为云社区《手拉手入门springboot+kafka》,作者:QGS。安装kafka启动Kafka本地环境需Java8+以上Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。Kafka启动方式有Zookeeper和Kraft,两种方式只能选择其中一种启动,不能同时使用......
  • Springboot配置文件Properties密码加密
    1.添加依赖<dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.3</version></dependency>2.启动类添加注解@EnableEncryptableProperties......
  • Springboot搭建dubbo+zookeeper本地项目
    1、下载zookeeper什么是zookeeper:https://www.cnblogs.com/Bernard94/p/17495775.html下载地址:https://dlcdn.apache.org/zookeeper/zookeeper-3.7.2/下载好解压后进入conf目录下,把‘zoo_sample.cfg’复制并改名为‘zoo.cfg’:修改配置文件的日志地址,修改到自己指定位置(非必......
  • SpringBoot笔记:SpringBoot启动参数配置
    /usr/local/jdk/jdk1.8.0_261/bin/java-jar-server\##服务模式,linux默认是server模式,window默认是client参数-XX:+HeapDumpOnOutOfMemoryError\##当OOM发生时自动生成HeapD......
  • IDEA2021.2.2使用Spring Initializr创建springboot项目
    使用SpringInitializr创建Springboot项目第一步:输入项目名称、项目所在路径等信息 在选择Java一项时,只有17、21、22选项。其中ProjectSDK一项,代表本地安装的JDK版本。Java一项,代表创建Spring工程时默认的JAVA版本。当选择最低值17时,点击下一步会弹出错误页面,提示“iThere......
  • 自己动手实现一个轻量无负担的任务调度ScheduleTask
    至于任务调度这个基础功能,重要性不言而喻,大多数业务系统都会用到,世面上有很多成熟的三方库比如Quartz,Hangfire,Coravel这里我们不讨论三方的库如何使用而是从0开始自己制作一个简易的任务调度技术栈用到了:BackgroundService和NCrontab库第一步我们定义一个简单的任务约定......
  • SpringBoot SpringCloud Spring Cloud Alibaba 版本对应关系
    最近公司的项目扫描出一些安全漏洞,于是让我给项目中的依赖升下级。有部分涉及到SpringBoot和SpringCloud,因此要考虑到兼容性,特此记录下查询各版本之间对应关系的方法。靠谱的方法还是要从官网得到,参考文章:工具篇--SpringBoot与SpringCloud的版本对应关系&SpringBoot与JDK对应关系......