将Quartz与Spring集成

本文介绍了如何在Java应用中结合Quartz和Spring Boot进行作业调度。通过利用Spring Boot的数据库初始化功能,避免手动SQL操作,配置Gradle依赖,设置应用配置以及创建自定义的SpringBeanJobFactory,实现了每分钟发送一次邮件的定时任务。同时,展示了如何定义作业和触发器,以实现Quartz在Spring环境中的无缝集成。
摘要由CSDN通过智能技术生成

在Java应用程序中调度作业时,Quartz是第一个考虑的工具。
Quartz是由最流行的RDBMS支持的作业调度程序。 这真的很方便,并且很容易与spring集成。 为了创建石英模式,您必须下载石英发行版并解压缩位于crystal-2.2.3 / docs / dbTables /中的文件夹。

根据您使用的数据库选择石英模式。 在我们的例子中,我们将使用本地h2数据库,因此将使用tables_h2.sql模式。
为了避免任何手动的SQL操作,我将使用Spring Boot数据库初始化功能。

让我们从gradle文件开始。

group 'com.gkatzioura'
version '1.0-SNAPSHOT'

apply plugin: 'java'

sourceCompatibility = 1.8

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE")
    }
}

apply plugin: 'idea'
apply plugin: 'spring-boot'

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.3.3.RELEASE'
    compile group: 'org.springframework', name: 'spring-context-support', version: '4.2.4.RELEASE'
    compile group: 'org.springframework', name:'spring-jdbc', version: '4.2.4.RELEASE'
    compile group: 'org.quartz-scheduler', name: 'quartz', version: '2.2.3'
    compile group: 'ch.qos.logback', name: 'logback-core', version:'1.1.3'
    compile group: 'ch.qos.logback', name: 'logback-classic',version:'1.1.3'
    compile group: 'org.slf4j', name: 'slf4j-api',version:'1.7.13'
    compile group: 'com.h2database', name: 'h2', version:'1.4.192'
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

除了石英,spring和h2依赖关系之外,我们还添加了spring-jdbc依赖关系,因为我们希望通过spring初始化数据库。

我们还将添加一个application.yml文件

spring:
  datasource:
    continueOnError: true
org:
  quartz:
    scheduler:
      instanceName: spring-boot-quartz-demo
      instanceId: AUTO
    threadPool:
      threadCount: 5
job:
  startDelay: 0
  repeatInterval: 60000
  description: Sample job
  key: StatisticsJob

由于架构创建语句(如果不存在则缺少创建),我将spring.datasource.continueOnError设置为false。 根据您的实施,解决方法将有所不同。

应用类别

package com.gkatzioura.springquartz;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

/**
 * Created by gkatzioura on 6/6/16.
 */
@SpringBootApplication
public class Application {

    public static void main(String[] args) {

        SpringApplication springApplication = new SpringApplication();
        ApplicationContext ctx = springApplication.run(Application.class,args);
    }
}

H2数据源配置由石英支持

package com.gkatzioura.springquartz.config;

import org.h2.jdbcx.JdbcDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

/**
 * Created by gkatzioura on 6/6/16.
 */
@Configuration
public class QuartzDataSource {

    //Since it a test database it will be located at the temp directory
    private static final String TMP_DIR = System.getProperty("java.io.tmpdir");

    @Bean
    public DataSource dataSource() {

        JdbcDataSource ds = new JdbcDataSource();
        ds.setURL("jdbc:h2:"+TMP_DIR+"/test");

        return ds;
    }

}

在我们的情况下,我们希望每分钟发送一次“垃圾邮件”电子邮件,因此我们定义了一个简单的电子邮件服务

package com.gkatzioura.springquartz.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * Created by gkatzioura on 6/7/16.
 */
@Service
public class EmailService {

    private static final Logger LOGGER = LoggerFactory.getLogger(EmailService.class);

    public void sendSpam() {

        LOGGER.info("Should send emails");
    }

}

我还将实现一个SpringBeanJobFactory

package com.gkatzioura.springquartz.quartz;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

/**
 * Created by gkatzioura on 6/7/16.
 */
public class QuartzJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {

    private transient AutowireCapableBeanFactory beanFactory;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        beanFactory = applicationContext.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {

        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job);
        return job;
    }
}

QuartzJobFactory将创建作业实例,并将使用应用程序上下文来注入定义的任何依赖项。

下一步是定义我们的工作

package com.gkatzioura.springquartz.job;

import com.gkatzioura.springquartz.service.EmailService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Created by gkatzioura on 6/6/16.
 */
public class EmailJob implements Job {

    @Autowired
    private EmailService cronService;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        cronService.sendSpam();
    }
}

最后一步是添加石英配置

package com.gkatzioura.springquartz.config;


import com.gkatzioura.springquartz.job.EmailJob;
import com.gkatzioura.springquartz.quartz.QuartzJobFactory;
import org.quartz.SimpleTrigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * Created by gkatzioura on 6/7/16.
 */
@Configuration
public class QuartzConfig {

    @Value("${org.quartz.scheduler.instanceName}")
    private String instanceName;

    @Value("${org.quartz.scheduler.instanceId}")
    private String instanceId;

    @Value("${org.quartz.threadPool.threadCount}")
    private String threadCount;

    @Value("${job.startDelay}")
    private Long startDelay;

    @Value("${job.repeatInterval}")
    private Long repeatInterval;

    @Value("${job.description}")
    private String description;

    @Value("${job.key}")
    private String key;

    @Autowired
    private DataSource dataSource;

    @Bean
    public org.quartz.spi.JobFactory jobFactory(ApplicationContext applicationContext) {

        QuartzJobFactory sampleJobFactory = new QuartzJobFactory();
        sampleJobFactory.setApplicationContext(applicationContext);
        return sampleJobFactory;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(ApplicationContext applicationContext) {

        SchedulerFactoryBean factory = new SchedulerFactoryBean();

        factory.setOverwriteExistingJobs(true);
        factory.setJobFactory(jobFactory(applicationContext));

        Properties quartzProperties = new Properties();
        quartzProperties.setProperty("org.quartz.scheduler.instanceName",instanceName);
        quartzProperties.setProperty("org.quartz.scheduler.instanceId",instanceId);
        quartzProperties.setProperty("org.quartz.threadPool.threadCount",threadCount);

        factory.setDataSource(dataSource);

        factory.setQuartzProperties(quartzProperties);
        factory.setTriggers(emailJobTrigger().getObject());

        return factory;
    }

    @Bean(name = "emailJobTrigger")
    public SimpleTriggerFactoryBean emailJobTrigger() {


        SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
        factoryBean.setJobDetail(emailJobDetails().getObject());
        factoryBean.setStartDelay(startDelay);
        factoryBean.setRepeatInterval(repeatInterval);
        factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
        factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
        return factoryBean;
    }

    @Bean(name = "emailJobDetails")
    public JobDetailFactoryBean emailJobDetails() {

        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(EmailJob.class);
        jobDetailFactoryBean.setDescription(description);
        jobDetailFactoryBean.setDurability(true);
        jobDetailFactoryBean.setName(key);

        return jobDetailFactoryBean;
    }
}

我们所做的是使用定义的QuartzJobFactory创建调度程序工厂bean,并注册了作业运行所需的触发器。 在我们的案例中,我们实现了一个简单的触发器,每分钟运行一次。

您可以在github上找到源代码

翻译自: https://www.javacodegeeks.com/2016/06/integrating-quartz-spring.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值