springboot 整合 quartz

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();

                            // 把triggerjobDetail注入到調度器
                            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();
    }
}
發佈了36 篇原創文章 · 獲贊 12 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章