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直接可以使用,要注意使用时版本需要对应。
包含的几张表的含义如下:
- qrtz_blob_triggers : 以Blob 类型存储的触发器。
- qrtz_calendars:存放日历信息, quartz可配置一个日历来指定一个时间范围。
- qrtz_cron_triggers:存放cron类型的触发器。
- qrtz_fired_triggers:存放已触发的触发器。
- qrtz_job_details:存放一个jobDetail信息。
- qrtz_job_listeners:job监听器。
- qrtz_locks: 存储程序的悲观锁的信息(假如使用了悲观锁)。
- qrtz_paused_trigger_graps:存放暂停掉的触发器。
- qrtz_scheduler_state:调度器状态。
- qrtz_simple_triggers:简单触发器的信息。
- qrtz_trigger_listeners:触发器监听器。
- 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。