Quartz框架

  • Post author:
  • Post category:其他




Quartz的介绍

关于Quartz的介绍网上有很多很多,但是在浏览了很多的文章之后,在这里优先推荐给大家的有如下几个以供大家理解,在这里感谢作者的辛苦贡献。

参考一(翻译版):

https://xuzongbao.gitbooks.io/quartz/content/chapter1.html


参考二(开发API):

https://www.quartz-scheduler.org/api/2.2.1/index.html


参考三(博客):

https://blog.csdn.net/guolong1983811/article/details/51501346

目前quartz框架更新到2.2.1版,网上有需要的SQL直接可以使用,要注意使用时版本需要对应。

包含的几张表的含义如下:

  1. qrtz_blob_triggers : 以Blob 类型存储的触发器。
  2. qrtz_calendars:存放日历信息, quartz可配置一个日历来指定一个时间范围。
  3. qrtz_cron_triggers:存放cron类型的触发器。
  4. qrtz_fired_triggers:存放已触发的触发器。
  5. qrtz_job_details:存放一个jobDetail信息。
  6. qrtz_job_listeners:job监听器。
  7. qrtz_locks: 存储程序的悲观锁的信息(假如使用了悲观锁)。
  8. qrtz_paused_trigger_graps:存放暂停掉的触发器。
  9. qrtz_scheduler_state:调度器状态。
  10. qrtz_simple_triggers:简单触发器的信息。
  11. qrtz_trigger_listeners:触发器监听器。
  12. qrtz_triggers:触发器的基本信息。



如何整合Quartz到Spring项目



引入quartz

pom.xml文件中引入quartz坐标

<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz</artifactId>
  <version>2.2.1</version>
</dependency>

<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz-jobs</artifactId>
  <version>2.2.1</version>
</dependency>



quartz.properties配置文件

quartz框架有默认的quartz.properties配置文件,要是和默认配置文件的名字相同并且在resource根目录下,则会自动覆盖默认的配置文件。要是不放在次位置,可以在xml配置文件中引用制定位置的配置文件。要是没有配置文件,则使用自带默认的。

# 调度器的名称
org.quartz.scheduler.instanceName = MyScheduler
# 线程数量 执行调度最大的线程数
org.quartz.threadPool.threadCount = 5
# 调度实例失效的检查时间间隔
org.quartz.jobStore.clusterCheckinInterval = 20000
# 数据保存方式 持久化到数据库
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
# 数据库平台 mysql
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# 表的前缀
org.quartz.jobStore.tablePrefix = QRTZ_
# 数据库别名 spring配置数据源 则这里配置的数据源不起作用 在spring中指定quartz的数据源
# org.quartz.jobStore.dataSource = myDS

# org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
# org.quartz.dataSource.myDS.URL = jdbc\:mysql\:(自己的DB的url)
# org.quartz.dataSource.myDS.user = (连接数据库的用户名)
# org.quartz.dataSource.myDS.password = (密码)
# org.quartz.dataSource.myDS.maxConnections = 5

上面的两步基本上将quartz就引入到项目中了。下面具体在以springmvc项目和springboot项目为例做一下配置。



SpringBoot项目中quartz的配置

在这里的配置若在quartz.properties配置文件中已经存在,则这里的会生效。

@Configuration
@ConditionalOnProperty(name = "quartz.enabled")
public class QuartzConfiguration {

    @Autowired
    AutowiringSpringBeanJobFactory autowiringSpringBeanJobFactory;

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) throws Exception {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setDataSource(dataSource);
        factory.setConfigLocation(new ClassPathResource("/quartz.properties"));
        factory.setJobFactory(autowiringSpringBeanJobFactory);
        factory.afterPropertiesSet();
        return factory;
    }
}

下面的这个Bean继承

SpringBeanJobFactory

和实现了

ApplicationContextAware

, 这样在具体的Job就可以使用Spring 注解的方式注入其他Bean。在这里实际上是将quartz交给Spring来统一管理。

@Component
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
    private transient AutowireCapableBeanFactory beanFactory;

    @Override
    public void setApplicationContext(final ApplicationContext context) {
        beanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job);
        return job;
    }
}



SpringMVC项目中quartz的配置

<!--配置Quartz 完全基于数据库,无需配置自定义的job类-->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
   <!-- 以下配置实现了job的持久化 (JobStoreTX)-->
   <!-- 事先在数据库里面配置好quartz的信息,然后quartz自动去读取,并实例化 -->
   <!-- 运行资源文件QuartzTable.sql文件,就配置好了相关的信息三张表 -->
   <property name="jobFactory">
      <bean class="com.xxx.xxx.business.quartz.factory.AutowiringSpringBeanJobFactory"/>
   </property>
   <!--指定spring中的数据源为 quartz的数据源 使用healthDB的数据源做为数据源-->
   <property name="dataSource" ref="dataSourceQuartz" />
   <property name="configLocation" value="classpath:quartz.properties" />
   <property name="applicationContextSchedulerContextKey"
           value="applicationContextKey" />
   <property name="autoStartup" value="true" />
</bean>
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
    private transient AutowireCapableBeanFactory beanFactory;

    @Override
    public void setApplicationContext(final ApplicationContext context) {
        beanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job);
        return job;
    }
}



定义一个Job

上面基本上将quartz的基本配置就做好了,quartz就直接可以使用了。

@Component
@DisallowConcurrentExecution // 有状态的JOB,防止同一时间重复执行
public class RealTimeJob implements Job {

    @Autowired
    SchedulerFactoryBean scheduler;
    @Autowired
    JobExecuteService jobExecuteService;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String nowDate = DateUtils.getNowDate();
        try {
            jobExecuteService.doRealTimeJob();
        } catch (Exception e) {
            logger.error("时间:"+ nowDate + ",执行任务出现异常...", e);
        }
    }
}

要执行的任务直接实现Job类,重写execute方法,这个类加入Job的调度之后,就会自动执行execute中的具体业务。



问题整理

  • Job和Trigger的关系:

一个Job可以绑定多个Trigger,但是一个Trigger只能指定一个Job。并且Trigger必须绑定Job,而Job可以不用绑定Trigger。



版权声明:本文为syp_24原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。