quartz在springboot下的简单配置(利用spring获取数据源)

本文介绍了如何在SpringBoot项目中配置Quartz,特别是如何利用Spring获取数据源。作者在配置过程中遇到了缺少相关教程、不支持XML配置等问题,并分享了从网上搜集和自己编写的代码片段,详细讲解了通过Spring托管Quartz、加载数据源的步骤。在配置中,需要注意Spring的beanName,以确保任务执行正常。此外,还提到了MySQL的校对集问题和删除数据库的注意事项。

quartz在springboot下的简单配置(利用spring获取数据源)

如题所示,配置方法如下

  • 从官网下载quartz的说明文档(就是为了获取那几张表)
  • 搭建springboot工程 此处省略
  • springboot集成quartz 下有代码
  • 遇到的问题

问题描述:百度了一下午就是没找到关于springboot配置quartz的相关文章,不是老旧的就是quartz单独的数据源,这里的代码有些是从网上扒来的,有些是自己写的

-原先的xml是这样配置的

    <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="dataSource" ref ="dataSource" />
        <property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
        <!--<property name="configLocation" value="classpath:quartz.properties"/>-->
        <property name="jobFactory" ref="myJobFactory"/>
    </bean>
    <bean id="myJobFactory" class="com.tmdaq.QuartzService.MyJobFactory"/>
  • 现在要改成这样才行
    • 首先来一波代码片段
  • 这段是我以前的代码 大致的意思是spring自动装配quartz
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;

public class MyJobFactory extends AdaptableJobFactory {

    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object jobInstance = super.createJobInstance(bundle);
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

-这段是我从网上找的 大致意思是springboot声明几个bean

import com.tmdaq.ip.quartz.MyJobFactory;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.*;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

@Configuration
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    private static Logger logger = Logger.getLogger(MyBeanDefinitionRegistryPostProcessor.class);
    private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
    private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        logger.info("Invoke Metho postProcessBeanDefinitionRegistry");
        registerBean(registry, "myJobFactory", MyJobFactory.class);
        registerBean(registry, "quartzScheduler", SchedulerFactoryBean.class);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        logger.info("Invoke Metho postProcessBeanFactory");
        BeanDefinition myJobFactory = beanFactory.getBeanDefinition("myJobFactory");
        BeanDefinition dataSource = beanFactory.getBeanDefinition("druidDataSource");
        // 这里可以设置属性,例如
        BeanDefinition bd = beanFactory.getBeanDefinition("quartzScheduler");
        MutablePropertyValues mpv =  bd.getPropertyValues();
        mpv.add("jobFactory" ,myJobFactory);
        mpv.add("dataSource",dataSource);
        mpv.addPropertyValue("applicationContextSchedulerContextKey",
        "applicationContextKey");
    }

    private void registerBean(BeanDefinitionRegistry registry, String name, Class<?> beanClass){
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());
        // 可以自动生成name
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, registry));
        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
    }
}

在配置的过程中,由于springboot不在支持xml方式的bean了 所以只能用编程的方式来声明 声明的过程就是这样的,坑了好就才搞出来
1.通过spring托管quartz的方法:
-2.在spring容器中加载quartz的autowire 这样能减少代码量 让代码更干净
-3.在spring中获取能autowire的类 ,并且注入到 quartzScheduler 中
-4.上一步spring就可以正常使用quartz了 但是还少一步 就是加载数据源 如果不加载数据源 他会读取项目中的quartz.properties 如果没有找到 就在他自己的路径中找(这个我没找到。。。)
-5.加载数据源 通过spring注入数据源 我这边使用的是druid 和第2部方法一样的
-最后一步就是写具体的执行任务了

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class buzhidaoxiedianshaJob implements Job {
    private Logger logger = Logger.getLogger(this.getClass());
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        logger.info("hahhahahaha");
    }
}

-在整个配置中 需要在加载的时候spring的beanName
MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory的形参:beanFactory的 属性

-这样的话就基本上没啥问题了
最后还想吐槽下几个问题 ,我是在mysql下装的 mysql mysql的校对集 默认的有个utf8-xxxx-ci 这个貌似是不区分大小写的
mysql 删除数据库的时候有可能删除不成功 需要手动删除对应数据库路径下的data/数据库名/文件夹下的所有文件 然后才能删除
quartz-innodb表中的所有建表语句都没有 default charset=utf8
今天的折腾成果 到此结束

Spring Boot 项目中整合 Quartz 并设置默认数据源配置,可以通过以下步骤实现。Spring Boot 提供了对 Quartz 的自动化支持,通过 `spring-boot-starter-quartz` 引入必要的依赖并进行配置[^3]。 ### 添加 Maven 依赖 首先,在 `pom.xml` 文件中添加 `spring-boot-starter-quartz` 依赖,它会自动引入 QuartzSpring 上下文支持、事务管理等所需组件[^2]。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> ``` 此外,如果使用数据库持久化任务信息,还需要添加数据库驱动依赖,例如 MySQL 或 PostgreSQL: ```xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> ``` ### 配置数据源 在 `application.yml` 或 `application.properties` 文件中配置默认数据源Spring Boot 默认使用 HikariCP 作为连接池,因此无需额外配置连接池类型。 ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/quartz_db username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver ``` ### 配置 Quartz 使用数据库存储 为了让 Quartz 使用数据库来存储调度信息(如作业和触发器),需要配置 `JobStoreTX` 并指定数据源。可以在 `application.yml` 中添加以下配置: ```yaml spring: quartz: job-store-type: jdbc dataSource: default: url: ${spring.datasource.url} username: ${spring.datasource.username} password: ${spring.datasource.password} driver-class-name: ${spring.datasource.driver-class-name} properties: org: quartz: scheduler: instanceName: MyScheduler instanceId: AUTO jobStore: class: org.quartz.impl.jdbcjobstore.JobStoreTX driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate tablesPrefix: QRTZ_ isClustered: true threadPool: class: org.quartz.simpl.SimpleThreadPool threadCount: 10 ``` ### 初始化 Quartz 数据库表 Quartz 提供了标准的 SQL 脚本用于创建所需的数据表,可以在 Quartz 的官方文档中到对应数据库的脚本。例如,对于 MySQL,执行以下 SQL 脚本以创建 Quartz 所需的表结构: ```sql DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; DROP TABLE IF EXISTS QRTZ_LOCKS; DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; DROP TABLE IF EXISTS QRTZ_TRIGGERS; DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; DROP TABLE IF EXISTS QRTZ_CALENDARS; CREATE TABLE QRTZ_JOB_DETAILS( SCHED_NAME VARCHAR(120) NOT NULL, JOB_NAME VARCHAR(200) NOT NULL, JOB_GROUP VARCHAR(200) NOT NULL, DESCRIPTION VARCHAR(250) NULL, JOB_CLASS_NAME VARCHAR(250) NOT NULL, IS_DURABLE VARCHAR(1) NOT NULL, IS_NONCONCURRENT VARCHAR(1) NOT NULL, IS_UPDATE_DATA VARCHAR(1) NOT NULL, REQUESTS_RECOVERY VARCHAR(1) NOT NULL, JOB_DATA BLOB NULL, PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) ); -- 其余表结构略... ``` ### 创建 Quartz 配置类(可选) 如果需要进一步自定义 Quartz 配置,例如添加监听器或注册作业,可以创建一个配置类: ```java import org.quartz.Scheduler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.quartz.SchedulerFactoryBean; @Configuration public class QuartzConfig { @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setDataSource(dataSource()); // 设置数据源 factory.setOverwriteExistingJobs(true); factory.setWaitForJobsToCompleteOnShutdown(true); return factory; } @Bean public Scheduler scheduler() { return schedulerFactoryBean().getScheduler(); } } ``` ### 创建并注册作业 定义一个实现了 `Job` 接口的类,并通过 `JobBuilder` 和 `TriggerBuilder` 注册作业和触发器: ```java import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class MyJob implements Job { @Override public void execute(JobExecutionContext context) { System.out.println("Quartz Job is running..."); } } // 注册作业 import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class JobScheduler { @Autowired private Scheduler scheduler; public void scheduleJob() throws SchedulerException { JobDetail job = JobBuilder.newJob(MyJob.class) .withIdentity("myJob", "group1") .build(); Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("myTrigger", "group1") .startNow() .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(10) .repeatForever()) .build(); scheduler.scheduleJob(job, trigger); } } ``` ### 总结 通过以上步骤,可以在 Spring Boot 项目中成功整合 Quartz,并配置默认数据源以实现任务的持久化存储。这种方式适用于需要高可用性和任务持久化的场景,如定时任务管理、作业调度系统等。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值