这里有些细节没有完善,例如配置文件参数的一些非空判断、配置值是否合法等等校验逻辑没有做,如果要设计成一个工业级的类库,这些方面必须要考虑。
JDBC数据源配置JDBC数据源这里用MySQL举例说明,先建一个调度任务配置表scheduling_task:
CREATE TABLE `schedule_task` ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '主键', edit_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', editor VARCHAR(32) NOT NULL DEFAULT 'admin' COMMENT '修改者', creator VARCHAR(32) NOT NULL DEFAULT 'admin' COMMENT '创建者', deleted BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '软删除标识', task_host_class VARCHAR(256) NOT NULL COMMENT '任务宿主类全类名', task_method VARCHAR(128) NOT NULL COMMENT '任务执行方法名', task_type VARCHAR(16) NOT NULL COMMENT '任务类型', task_description VARCHAR(64) NOT NULL COMMENT '任务描述', cron_expression VARCHAR(128) COMMENT 'cron表达式', time_zone VARCHAR(32) COMMENT '时区', interval_milliseconds BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '执行间隔时间', initial_delay_milliseconds BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '初始延迟执行时间', UNIQUE uniq_class_method (task_host_class, task_method) ) COMMENT '调度任务配置表';其实具体的做法和JSON配置差不多,先引入spring-boot-starter-jdbc,接着编写MysqlSchedulingConfigurer:
// DAO @RequiredArgsConstructor public class MysqlScheduleTaskDao { private final JdbcTemplate jdbcTemplate; private static final ResultSetExtractor<List<ScheduleTask>> MULTI = r -> { List<ScheduleTask> tasks = Lists.newArrayList(); while (r.next()) { ScheduleTask task = new ScheduleTask(); tasks.add(task); task.setId(r.getLong("id")); task.setCronExpression(r.getString("cron_expression")); task.setInitialDelayMilliseconds(r.getLong("initial_delay_milliseconds")); task.setIntervalMilliseconds(r.getLong("interval_milliseconds")); task.setTimeZone(r.getString("time_zone")); task.setTaskDescription(r.getString("task_description")); task.setTaskHostClass(r.getString("task_host_class")); task.setTaskMethod(r.getString("task_method")); task.setTaskType(r.getString("task_type")); } return tasks; }; public List<ScheduleTask> selectAllTasks() { return jdbcTemplate.query("SELECT * FROM schedule_task WHERE deleted = 0", MULTI); } } // MysqlSchedulingConfigurer @RequiredArgsConstructor public class MysqlSchedulingConfigurer extends AbstractSchedulingConfigurer { private final MysqlScheduleTaskDao mysqlScheduleTaskDao; @Override protected List<InternalTaskProperties> loadTaskProperties() throws Exception { List<InternalTaskProperties> target = Lists.newArrayList(); List<ScheduleTask> tasks = mysqlScheduleTaskDao.selectAllTasks(); if (!tasks.isEmpty()) { for (ScheduleTask task : tasks) { ScheduleTaskType scheduleTaskType = ScheduleTaskType.fromType(task.getTaskType()); if (ScheduleTaskType.CRON == scheduleTaskType) { target.add(CronTaskProperties.builder() .taskMethod(task.getTaskMethod()) .cronExpression(task.getCronExpression()) .timeZone(task.getTimeZone()) .taskDescription(task.getTaskDescription()) .taskHostKlass(task.getTaskHostClass()) .build()); } if (ScheduleTaskType.FIXED_DELAY == scheduleTaskType) { target.add(FixedDelayTaskProperties.builder() .taskMethod(task.getTaskMethod()) .intervalMilliseconds(String.valueOf(task.getIntervalMilliseconds())) .initialDelayMilliseconds(String.valueOf(task.getInitialDelayMilliseconds())) .taskDescription(task.getTaskDescription()) .taskHostKlass(task.getTaskHostClass()) .build()); } if (ScheduleTaskType.FIXED_RATE == scheduleTaskType) { target.add(FixedRateTaskProperties.builder() .taskMethod(task.getTaskMethod()) .intervalMilliseconds(String.valueOf(task.getIntervalMilliseconds())) .initialDelayMilliseconds(String.valueOf(task.getInitialDelayMilliseconds())) .taskDescription(task.getTaskDescription()) .taskHostKlass(task.getTaskHostClass()) .build()); } } } return target; } }记得引入spring-boot-starter-jdbc和mysql-connector-java并且激活MysqlSchedulingConfigurer配置。插入一条记录:
INSERT INTO `schedule_task`(`id`, `edit_time`, `create_time`, `editor`, `creator`, `deleted`, `task_host_class`, `task_method`, `task_type`, `task_description`, `cron_expression`, `time_zone`, `interval_milliseconds`, `initial_delay_milliseconds`) VALUES (1, '2020-03-30 23:46:10', '2020-03-30 23:46:10', 'admin', 'admin', 0, 'club.throwable.schedule.Tasks', 'processTask1', 'FIXED_DELAY', '测试任务', NULL, NULL, 10000, 5000);