
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="ActionCronTrigger"/>
<ref bean="ActionOrderCronTrigger"/>
<ref bean="InquiryCronTrigger"/>
</list>
</property>
</bean>
其中:
<ref bean="ActionCronTrigger"/>
<ref bean="ActionOrderCronTrigger"/>
<ref bean="InquiryCronTrigger"/>
配置对应的定时任务,可配置多个,名称要唯一,对应的是第二步中配置的CronTriggerFactoryBean
CronTriggerFactoryBean配置,由于要实现动态读取定时任务周期时间,所以我们要写一个类实现CronTriggerFactoryBean,类的内容如下:
public class InitCronTriggerFactoryBean extends CronTriggerFactoryBean implements Serializable {
private static final long serialVersionUID = 1L
private SysParamServiceImpl sysParamServiceImpl
private String key
public void setKey(String key)
{
this.key = key
}
public void setSysParamServiceImpl(SysParamServiceImpl sysParamServiceImpl)
{
this.sysParamServiceImpl = sysParamServiceImpl
setCronExpression(getCronExpressionFromDB())
}
private String getCronExpressionFromDB()
{
if(StringUtils.isEmpty(key))
return "0 0 0/1 * * ?"
SysParam sysParam = new SysParam()
try
{
sysParam = sysParamServiceImpl.getNameByKey(key)
}
catch (Exception e)
{
e.printStackTrace()
}
if(sysParam != null &&!StringUtils.isEmpty(sysParam.getParamValue()))
return sysParam.getParamValue()
return "0 0 0/1 * * ?"
}
}
简单说明一下:key是用来查询数据库配置的CronExpression表达式的查询条件,SysParamServiceImpl 是实现查询的类,这几个参数都要从spring配置的CronTriggerFactoryBean参数获取,注意,配置的时候,key值的配置要在SysParamServiceImpl 的配置之前,否则报空指针
spring配置CronTriggerFactoryBean:
实现了CronTriggerFactoryBean之后,开始配置CronTriggerFactoryBean,现在配置的是InitCronTriggerFactoryBean :
<bean id="InquiryCronTrigger" class="cn.com.shopec.quartz.utils.InitCronTriggerFactoryBean">
<property name="jobDetail" ref="InquiryJobDetail" />
<property name="key" value="inquiryQuartzParam" />
<property name="sysParamServiceImpl" ref="sysParamServiceImpl" />
</bean>
id对应quartz定时任务配置的<ref bean="InquiryCronTrigger"/>,参数有三个,第二个和第三个是InitCronTriggerFactoryBean设置内容需要的,第一个<property name="jobDetail" ref="InquiryJobDetail" />则是定时任务执行业务逻辑的类
ps:<property name="sysParamServiceImpl" ref="sysParamServiceImpl" />,这个要配置对应的bean,我的是
<bean id="sysParamServiceImpl" class="cn.com.shopec.core.system.service.impl.SysParamServiceImpl">
</bean>
配置对应的定时任务执行业务方法的类:
<bean id="InquiryJobDetail"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="durability" value="true" />
<property name="jobClass" value="cn.com.shopec.quartz.utils.InquiryQuartz" />
<property name="jobDataAsMap">
<map>
<entry key ="inquiryServiceImpl" value-ref="inquiryServiceImpl"/>
</map>
</property>
</bean>
简单说明一下:<property name="jobClass" value="cn.com.shopec.quartz.utils.InquiryQuartz" />配置的是你需要定时执行的类,<property name="jobDataAsMap">下面配置的是定时执行类中需要用到的其他类,这是由于项目启动执行定时任务不能在定时任务类中实例化这些类,要配置才行。
对应的定时任务执行类:
public class InquiryQuartz extends QuartzJobBean {
@Autowired
private InquiryServiceImpl inquiryServiceImpl
@Override
protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException
{
// 实例化接口
inquiryServiceImpl = (InquiryServiceImpl) arg0.getJobDetail().getJobDataMap().get("inquiryServiceImpl")
// 执行业务方法
quartzStart()
}
public void quartzStart(){
// 业务方法...
}
}
说明一下:必须要实现QuartzJobBean 接口
至此,就可以完成可配置CronExpression表达式的定时任务了!1
1、去quartz官网下载quartz2.2.2版本的压缩包,quartz下载,注意:quartz2.3.0版本的在docs目录下没有发现dbtable目录(存放生成数据库表的sql文件的目录)。2、执行创建数据库表的sql文件,我使用的是mysql数据库。
生成的表结构
3、在springboot项目中配置quartz。
3.1、两种方式配置quartz,
3.1.1、第一种是使用自定义的quartz.properties,这是简单配置,如果有其他配置可以参考,quartz.properties配置详情
org.quartz.jobStore.useProperties:true
#org.quartz.scheduler.instanceName: quartzScheduler
#org.quartz.scheduler.instanceId = AUTO
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 15
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.isClustered = false
#org.quartz.jobStore.clusterCheckinInterval=20000
org.quartz.jobStore.tablePrefix = qrtz_
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.maxMisfiresToHandleAtATime = 20
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
登录后复制
3.1.2、使用配置文件配置springboot中的SchedulerFactoryBean。
@Configuration
public class SchedulerConfig implements SchedulerFactoryBeanCustomizer {
@Autowired
private DataSource dataSource
@Override
public void customize(SchedulerFactoryBean schedulerFactoryBean) {
schedulerFactoryBean.setStartupDelay(10)
schedulerFactoryBean.setOverwriteExistingJobs(true)
schedulerFactoryBean.setDataSource(dataSource)
ClassPathResource resource = new ClassPathResource("quartz.properties")
Properties properties = new Properties()
InputStream in= null
try {
in = resource.getInputStream()
BufferedReader bf = new BufferedReader(new InputStreamReader(in, "UTF-8"))
properties.load(bf)
schedulerFactoryBean.setQuartzProperties(properties)
} catch (IOException e) {
e.printStackTrace()
}
}
}
登录后复制
3.2.1、第二种方式是在application.properties文件中的配置,application.properties文件中的spring.quartz.properties. 加上quartz.properties中的键值对,效果与quartz.properties类似。
spring.quartz.properties.org.quartz.jobStore.tablePrefix = qrtz_
spring.quartz.properties.org.quartz.threadPool.threadCount = 10
登录后复制
项目中配置org.quartz.jobStore.tablePrefix = qrtz_,这个配置是默认查询数据库中表的前缀,默认是QRTZ_,以下sql中通过rpt方法组装一条新的sql,替换掉{0},{1},如果没有明确声明就会使用默认值 org.quartz.jobStore.tablePrefix = QRTZ_,org.quartz.scheduler.instanceName: quartzScheduler。
如果进行简单的定时任务,可以使用springboot中默认的quartz配置。
3.2.2 自定义配置springboot中的SchedulerFactoryBean。
@Configuration
public class SchedulerConfig implements SchedulerFactoryBeanCustomizer {
@Autowired
private DataSource dataSource
@Override
public void customize(SchedulerFactoryBean schedulerFactoryBean) {
schedulerFactoryBean.setStartupDelay(10)
schedulerFactoryBean.setOverwriteExistingJobs(true)
schedulerFactoryBean.setDataSource(dataSource)
}
}
登录后复制
4、新建Job
public class TestJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println(System.nanoTime())
}
}
登录后复制
5、数据库中新增job任务脚本,com.example.quartzdemo.job.TestJob是我本地的测试Job,需要修改成你自己Job类。
INSERT INTO `qrtz_job_details` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('quartzScheduler', 'test2Job', 'testGroup', NULL, 'com.example.quartzdemo.job.TestJob', '1', '0', '0', '0', NULL)
INSERT INTO `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('quartzScheduler', 'testTrigger2', 'testTriggerGroup', 'test2Job', 'testGroup', NULL, '1554122914000', '1554122913000', '5', 'ACQUIRED', 'CRON', '1554039857000', '0', NULL, '0', NULL)
INSERT INTO `qrtz_cron_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('quartzScheduler', 'testTrigger2', 'testTriggerGroup', '0/1 * * * * ?', 'Asia/Shanghai')
登录后复制
6、启动项目,查看控制台打印的日志,成功
Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。本文主要介绍 Quartz 的基本使用,文中使用到的软件及版本:Java 1.8.0_191、Quartz 2.3.2、SpringBoot 2.4.4、MySQL 5.7。1、Quartz 核心概念
Job 表示一个工作,要执行的具体内容。
JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。一个 JobDetail 可对应多个 Trigger。
Trigger 代表一个调度参数的配置,什么时候去调。一个 Trigger 对应 一个 JobDetail。
Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。
2、Quartz 常用配置
2.1、Quartz 主配置
1、org.quartz.scheduler.instanceName scheduler 实例名称,默认值为 'QuartzScheduler'
2、org.quartz.scheduler.instanceId scheduler实例Id,必须唯一;启用集群可设为 'AUTO',默认值为 'NON_CLUSTERED'
3、org.quartz.scheduler.threadName 线程名称,默认值为 instanceName + '_QuartzSchedulerThread'
4、org.quartz.scheduler.makeSchedulerThreadDaemon 调度程序的主线程是否设为守护线程,默认值为 false
2.2、ThreadPool 配置
1、org.quartz.threadPool.class ThreadPool实现的类名,默认值为 'org.quartz.simpl.SimpleThreadPool'
2、org.quartz.threadPool.threadCount 线程数,默认值为 10
3、org.quartz.threadPool.threadPriority 线程优先级,默认值 5
2.3、JobStore 配置
org.quartz.jobStore.class 任务存储实现类名,可设为 org.quartz.simpl.RAMJobStore、org.quartz.impl.jdbcjobstore.JobStoreTX(quartz管理事务)、org.quartz.impl.jdbcjobstore.JobStoreCMT(应用程序管理事务)、org.terracotta.quartz.TerracottaJobStore;当设置为jdbc存储时,有以下属性可以调整设置:
1、org.quartz.jobStore.driverDelegateClass 驱动代理类,看设置为标准的 jdbc 驱动程序:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
2、org.quartz.jobStore.dataSource 数据源名称
3、org.quartz.jobStore.tablePrefix JDBCJobStore的表前缀如果使用不同的表前缀,则可以在同一数据库中拥有多组Quartz表;默认值 'QRTZ_'
4、org.quartz.jobStore.useProperties 指示JobDataMaps中的所有值都将是字符串,避免了将非String类序列化为BLOB时可能产生的类版本控制问题
5、org.quartz.jobStore.isClustered 是否开启集群,如果有多个 Quartz 实例使用同一组数据库表,则此属性必须设置为 true,默认值为 false
6、org.quartz.jobStore.clusterCheckinInterval 设置此实例检入与群集的其他实例的频率(以毫秒为单位),默认值为 15000
2.4、DataSource 配置
1、org.quartz.dataSource.NAME.driver JDBC 驱动程序
2、org.quartz.dataSource.NAME.URL JDBC URL
3、org.quartz.dataSource.NAME.user 数据库用户名
4、org.quartz.dataSource.NAME.password 数据库密码
5、org.quartz.dataSource.NAME.maxConnections 最大连接数,默认值 10
6、org.quartz.dataSource.NAME.validationQuery 验证sql
7、org.quartz.dataSource.NAME.idleConnectionValidationSeconds 空闲连接检测间隔,默认值 50
8、org.quartz.dataSource.NAME.validateOnCheckout 获取连接后是否验证连接,默认值 false
9、org.quartz.dataSource.NAME.discardIdleConnectionsSeconds 空闲连接多长时间后丢弃该连接,0 表示禁用该功能,默认值为 0。
或者使用容器提供的数据源:
1、org.quartz.dataSource.NAME.jndiURL 数据源的 jndi
2、org.quartz.dataSource.NAME.java.naming.security.principal jndi 需要的用户名
3、org.quartz.dataSource.NAME.java.naming.security.credentials jndi 需要的密码
3、Quartz JDBCJobStore表说明
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)