Quartz?
任務(wù)調(diào)度框架“Quartz”是OpenSymphony開源組織在Job scheduling領(lǐng)域又一個開源項目脊岳,是完全由java開發(fā)的一個開源的任務(wù)日程管理系統(tǒng),“任務(wù)進度管理器”就是一個在預(yù)先確定(被納入日程)的時間到達時滚局,負責執(zhí)行(或者通知)其他軟件組件的系統(tǒng)曲梗。
- 在springboot中通過讀取數(shù)據(jù)庫的定時任務(wù)信息纤垂,動態(tài)生成quartz定時任務(wù)
- 導(dǎo)入依賴
- quartz-jobs
- spring-boot-starter-quartz
- druid-spring-boot-starter
- 在項目中添加quartz.properties文件
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#
#默認或是自己改名字都行
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
#如果使用集群逸吵,instanceId必須唯一,設(shè)置成AUTO
org.quartz.scheduler.instanceId = AUTO
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.misfireThreshold: 60000
#============================================================================
# Configure JobStore
#============================================================================
#存儲方式使用JobStoreTX厢破,也就是數(shù)據(jù)庫
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#使用自己的配置文件
org.quartz.jobStore.useProperties:true
#數(shù)據(jù)庫中quartz表的表名前綴
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:qzDS
#是否使用集群(如果項目只部署到 一臺服務(wù)器荣瑟,就不用了)
org.quartz.jobStore.isClustered = true
#============================================================================
# Configure Datasources
#============================================================================
#配置數(shù)據(jù)源
#org.quartz.dataSource.qzDS.connectionProvider.class:org.quartz.utils.PoolingConnectionProvider
org.quartz.dataSource.qzDS.driver:com.mysql.cj.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:123
org.quartz.dataSource.qzDS.maxConnections:10
注:(這樣就不會加載自帶的properties文件)
此文件的內(nèi)容主要分為:scheduler,ThreadPool摩泪,JobStore笆焰,plugin,Datasources等部分
- 在數(shù)據(jù)庫中創(chuàng)建quartz相關(guān)的表
- 進入quartz的官網(wǎng)http://www.quartz-scheduler.org/加勤,點擊Downloads
- 下載后在目錄\docs\dbTables下有常用數(shù)據(jù)庫創(chuàng)建quartz表的腳本仙辟,例如:“tables_mysql.sql”
- 自定義MyJobFactory,解決spring不能在quartz中注入bean的問題
@Component
public class MyJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);//qz框架反射機制創(chuàng)建jobBean
capableBeanFactory.autowireBean(jobInstance); //這一步解決不能spring注入bean的問題
return jobInstance;
}
}
Job是由quartz創(chuàng)建鳄梅,不是由spring創(chuàng)建
AutowireCapableBeanFactory是spring提供的接口:對于想要擁有自動裝配能力叠国,并且想把這種能力暴露給外部應(yīng)用的BeanFactory類需要實現(xiàn)此接口。
正常情況下戴尸,不要使用此接口粟焊,應(yīng)該更傾向于使用BeanFactory或者ListableBeanFactory接口。此接口主要是針對框架之外,沒有向Spring托管Bean的應(yīng)用项棠。通過暴露此功能悲雳,Spring框架之外的程序,具有自動裝配等Spring的功能香追。
需要注意的是合瓢,ApplicationContext接口并沒有實現(xiàn)此接口,因為應(yīng)用代碼很少用到此功能透典,如果確實需要的話晴楔,可以調(diào)用ApplicationContext的getAutowireCapableBeanFactory方法,來獲取此接口的實例峭咒。
如果一個類實現(xiàn)了此接口税弃,那么很大程度上它還需要實現(xiàn)BeanFactoryAware接口。它可以在應(yīng)用上下文中返回BeanFactory
- 創(chuàng)建調(diào)度器schedule
@Configuration
public class QuartzConfigration {
@Autowired
private MyJobFactory myJobFactory; //自定義的factory
//獲取工廠bean
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {//任務(wù)調(diào)度器由調(diào)度器工廠創(chuàng)建
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
try {
schedulerFactoryBean.setQuartzProperties(quartzProperties());//調(diào)度器工廠讀取配置文件quartz.properties
/**
* Job默認是由quartz框架創(chuàng)建凑队,這里改成了自定義的Job工廠则果,而這個自定義的工廠已經(jīng)被注入到spring的上下文中了
* 解決了Job拿不到spring上下文里的javaBean的問題
*/
schedulerFactoryBean.setJobFactory(myJobFactory);
return schedulerFactoryBean;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//指定quartz.properties
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
//創(chuàng)建schedule
@Bean(name = "scheduler")//外部程序調(diào)用這個方法,得到任務(wù)調(diào)度器
public Scheduler scheduler() {
return schedulerFactoryBean().getScheduler();
}
}
@Configuration注解
從Spring3.0漩氨,@Configuration用于定義配置類西壮,可替換xml配置文件,
被注解的類內(nèi)部包含有一個或多個被@Bean注解的方法才菠,這些方法將會被AnnotationConfigApplicationContext
或AnnotationConfigWebApplicationContext類進行掃描茸时,并用于構(gòu)建bean定義贡定,初始化Spring容器赋访。
注意:
- @Configuration不可以是final類型;
- @Configuration不可以是匿名類缓待;
- 嵌套的configuration必須是靜態(tài)類蚓耽。
@Bean
一般是跟@Configuration一起配合著使用,用于創(chuàng)建javaBean旋炒,將創(chuàng)建出來的javaBean存到spring的上下文中去
- 創(chuàng)建自定義任務(wù)
注1:實現(xiàn)接口org.quartz.Job或org.springframework.scheduling.quartz.QuartzJobBean創(chuàng)建任務(wù)步悠,可通過JobExecutionContext傳參
更新quartz中的任務(wù)
首先我們需要自己創(chuàng)建一張表t_schedule_trigger,用來存放trigger的信息瘫镇,然后從數(shù)據(jù)庫讀取這些信息來隨時更新定時任務(wù)
注意:job_name存放的任務(wù)類的全路徑鼎兽,在quartz中通過jobName和jobGroup來確定trigger的唯一性,所以這兩列為聯(lián)合唯一索引注1:t_schedule_trigger的子表t_schedule_trigger_param還可以用來傳遞額外添加到任務(wù)中的參數(shù)
@Test
public void add() throws Exception {
scheduleTrigger.setId(null);
scheduleTrigger.setCron("*/5 * * * * ?");
scheduleTrigger.setStatus("1");
scheduleTrigger.setJobName("com.howe.q03.quartz.MyJob1");
scheduleTrigger.setJobGroup("group-1");
scheduleTriggerService.add(scheduleTrigger);
}