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
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: 20
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.misfireThreshold: 60000
# Configure JobStore
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:true
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:qzDS
# Configure Datasources
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://127.0.0.1:3306/qinwei?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:123456
org.quartz.dataSource.qzDS.maxConnection:10
CREATE TABLE `schedule_triggers` (
`id` int(11) NOT NULL,
`cron` varchar(255) NOT NULL COMMENT '時間表達式 ',
`status` int(1) NOT NULL COMMENT '使用狀態 0:禁用 1:啓用 ',
`jobName` varchar(255) NOT NULL COMMENT '任務名稱',
`jobGroup` varchar(255) NOT NULL COMMENT '任務分組'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ScheduleTrigger.java
public class ScheduleTrigger {
private Integer id;
private String cron; // 時間表達式
private String status; // 使用狀態 0:禁用 1:啓用
private String jobName; // 任務名稱
private String jobGroup; // 任務分組
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
}
MyJobFactory.java
@Component
public class MyJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
// 這一步解決不能spring注入bean的問題
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
quartz配置類
@Configuration
public class QuartzConfigration {
@Autowired
private MyJobFactory myJobFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
try {
schedulerFactoryBean.setQuartzProperties(quartzProperties());
} catch (IOException e) {
e.printStackTrace();
}
schedulerFactoryBean.setJobFactory(myJobFactory);
return schedulerFactoryBean;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
@Bean(name = "scheduler")
public Scheduler scheduler() {
return schedulerFactoryBean().getScheduler();
}
}
@Mapper
public interface ScheduleTriggerDao {
@Select("SELECT * FROM SCHEDULE_TRIGGERS")
List<ScheduleTrigger> queryAll();
}
ScheduleTriggerService.java
@Service
public class ScheduleTriggerService {
private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleTriggerService.class);
@Autowired
private Scheduler scheduler;
@Autowired
private ScheduleTriggerDao scheduleTriggerDao;
@SuppressWarnings({ "unchecked" })
public void refreshTrigger() {
try {
List<ScheduleTrigger> jobList = scheduleTriggerDao.queryAll();
if (jobList != null && jobList.size() > 0) {
for (ScheduleTrigger scheduleTrigger : jobList) {
String status = scheduleTrigger.getStatus();// 該任務觸發器目前的狀態
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleTrigger.getJobName(),
scheduleTrigger.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 說明本條任務還沒有添加到quartz中
if (trigger == null) {
// 如果是禁用,則不用創建觸發器
if ("0".equals(status)) {
continue;
}
JobDetail jobDetail = null;
try {
// 創建JobDetail(數據庫中job_name存的任務全路徑,這裏就可以動態的把任務注入到JobDetail中)
Class<? extends Job> jobName = (Class<? extends Job>) Class
.forName(scheduleTrigger.getJobName());
jobDetail = JobBuilder.newJob(jobName)
.withIdentity(scheduleTrigger.getJobName(), scheduleTrigger.getJobGroup()).build();
// 表達式調度構建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
.cronSchedule(scheduleTrigger.getCron());
// 按新的cronExpression表達式構建一個新的trigger
trigger = TriggerBuilder.newTrigger()
.withIdentity(scheduleTrigger.getJobName(), scheduleTrigger.getJobGroup())
.withSchedule(scheduleBuilder).build();
// 把trigger和jobDetail注入到調度器
scheduler.scheduleJob(jobDetail, trigger);
} catch (Exception e) {
LOGGER.error("創建定時任務失敗!", e);
}
} else {
// 說明查出來的這條任務,已經設置到quartz中了
// Trigger已存在,先判斷是否需要刪除,如果不需要,再判定是否時間有變化
if ("0".equals(scheduleTrigger.getStatus())) {
// 如果是禁用,從quartz中刪除這條任務
JobKey jobKey = JobKey.jobKey(scheduleTrigger.getJobName(), scheduleTrigger.getJobGroup());
scheduler.deleteJob(jobKey);
continue;
}
String searchCron = scheduleTrigger.getCron();// 獲取數據庫的
String currentCron = trigger.getCronExpression();
if (!searchCron.equals(currentCron)) {
// 說明該任務有變化,需要更新quartz中的對應的記錄
// 表達式調度構建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron);
// 按新的cronExpression表達式重新構建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder)
.build();
// 按新的trigger重新設置job執行
scheduler.rescheduleJob(triggerKey, trigger);
}
}
}
}
} catch (Exception e) {
LOGGER.error("刷新觸發器發生異常," + this.getClass().getName() + ".refreshTrigger ,異常信息:", e);
}
}
}
Myjob.java
@Component
public class Myjob implements Job {
public static final Logger logger = LoggerFactory.getLogger(Myjob.class);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
CronTrigger trigger = (CronTrigger) context.getTrigger();
String cronExpression = trigger.getCronExpression();
String name = trigger.getKey().getName();
String group = trigger.getKey().getGroup();
logger.info("cronExpression: {}; triggerName: {}; triggerGroup: {}", cronExpression, name, group);
}
}
QuartzTest.java
@Controller
public class QuartzTest {
@Autowired
private ScheduleTriggerService scheduleTriggerService;
@RequestMapping("refreshTrigger")
public void refreshTrigger() {
scheduleTriggerService.refreshTrigger();
}
}