> 文章列表 > Springboot整合Quartz实现定时任务数据库动态配置

Springboot整合Quartz实现定时任务数据库动态配置

Springboot整合Quartz实现定时任务数据库动态配置

文章目录

  • Springboot整合Quartz实现定时任务数据库动态配置
    • 1.引入相关依赖,包括Spring Boot、Quartz和数据库驱动等,例如:
    • 2.配置数据源,例如:
    • 3.创建QuartzConfig实体类,用于表示定时任务的配置信息,例如:
    • 4.创建MyJob类,用于实现具体的定时任务逻辑,例如:
    • 5.创建定时任务配置的Repository接口,例如:
    • 6.创建定时任务调度器的配置类,例如:
    • 7.创建QuartzConfigService类,用于初始化调度器,并从数据库中读取定时任务配置信息,例如:

Springboot整合Quartz实现定时任务数据库动态配置

以下是Spring Boot整合Quartz实现定时任务数据库动态配置的步骤:

1.引入相关依赖,包括Spring Boot、Quartz和数据库驱动等,例如:

<!-- Quartz依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId>
</dependency><!-- 数据库连接依赖 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>

2.配置数据源,例如:

spring.datasource.url=jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

3.创建QuartzConfig实体类,用于表示定时任务的配置信息,例如:

@Entity
@Data
public class QuartzConfig {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;// 任务名称private String name;// 任务分组private String group;// Cron表达式private String cronExpression;// Job描述private String jobDescription;
}

4.创建MyJob类,用于实现具体的定时任务逻辑,例如:

public class MyJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {// 获取JobDataMap中的参数信息JobDataMap dataMap = context.getMergedJobDataMap();// 不同任务 相同的 key 可以拿到不同的 valueString param1 = dataMap.getString("param1");// 不同任务 相同的 key 可以拿到不同的 valueString param2 = dataMap.getString("param2");// 执行具体的定时任务逻辑,使用参数信息等System.out.println("Hello, Quartz!");}
}

5.创建定时任务配置的Repository接口,例如:

@Repository
public interface QuartzConfigRepository extends JpaRepository<QuartzConfig, Long> {// 省略自定义查询方法// 新增定时任务配置QuartzConfig save(QuartzConfig quartzConfig);
}

6.创建定时任务调度器的配置类,例如:

@Configuration
public class QuartzConfig {@Autowiredprivate DataSource dataSource;// 配置SchedulerFactoryBean,用于创建调度器实例@Beanpublic SchedulerFactoryBean schedulerFactoryBean() {// 创建 SchedulerFactoryBean 实例SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();// 设置数据源schedulerFactoryBean.setDataSource(dataSource);// 设置 ApplicationContext 在 SchedulerContext 中的 key 值,在 Scheduler 调度任务时,可以通过 SchedulerContext 获取当前的 ApplicationContext 对象schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");// 设置任务执行器schedulerFactoryBean.setTaskExecutor(schedulerThreadPool());// 设置是否自动启动 SchedulerschedulerFactoryBean.setAutoStartup(true);// 设置是否覆盖已存在的 job/*当该属性设置为 true 时,如果 Quartz 发现已有相同名称和分组的触发器和任务存在,则会替换掉原来的触发器和任务。如果该属性设置为 false,则不会覆盖已经存在的任务,而是抛出一个异常。需要注意的是,如果调度器中有正在执行的任务,它们不受此属性的影响,仍然会继续执行直到完成。*/schedulerFactoryBean.setOverwriteExistingJobs(true);// 调用了方法 quartzProperties() 来获取 Properties 对象schedulerFactoryBean.setQuartzProperties(quartzProperties());// 返回创建好的 SchedulerFactoryBean 实例return schedulerFactoryBean;}// 配置线程池,用于执行定时任务@Beanpublic TaskExecutor schedulerThreadPool() {// 创建 ThreadPoolTaskExecutor 实例ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();// 设置线程池中线程的名称前缀为 "quartz-thread-"executor.setThreadNamePrefix("quartz-thread-");// 设置核心线程数为 5executor.setCorePoolSize(5);// 设置最大线程数为 10executor.setMaxPoolSize(10);// 设置队列容量为 1024executor.setQueueCapacity(1024);// 初始化线程池executor.initialize();// 返回创建好的 ThreadPoolTaskExecutor 实例。这个实例可以用来执行调度任务return executor;}// 配置Quartz的属性,例如jobStore、schedulerName等private Properties quartzProperties() {// 创建一个 Properties 实例,用于存储 Quartz 的配置属性Properties properties = new Properties();// 设置调度器实例的名称properties.setProperty("org.quartz.scheduler.instanceName", "HandsomeScheduler");// 让 Quartz 自动生成调度器实例 IDproperties.setProperty("org.quartz.scheduler.instanceId", "AUTO");// 指定 Quartz 使用数据库作为作业存储器,并启用事务properties.setProperty("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");// 指定 Quartz 使用标准 JDBC 委托类来管理数据库和作业存储器properties.setProperty("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");// 指定 Quartz 使用名为 "HandsomeDB" 的数据源properties.setProperty("org.quartz.jobStore.dataSource", "HandsomeDB");// 指定 Quartz 在数据库中使用的表名前缀properties.setProperty("org.quartz.jobStore.tablePrefix", "QRTZ_");// 设置 Quartz 集群模式为非集群模式properties.setProperty("org.quartz.jobStore.isClustered", "false");// 指定 "HandsomeDB" 数据源使用的 JDBC 驱动程序properties.setProperty("org.quartz.dataSource.HandsomeDB.driver", "com.mysql.cj.jdbc.Driver");// 指定 "HandsomeDB" 数据源使用的 JDBC URLproperties.setProperty("org.quartz.dataSource.myDS.URL", "jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai");// 指定 "HandsomeDB" 数据源使用的用户名properties.setProperty("org.quartz.dataSource.HandsomeDB.user", "root");// 指定 "HandsomeDB" 数据源使用的密码properties.setProperty("org.quartz.dataSource.HandsomeDB.password", "root");// 指定 "HandsomeDB" 数据源允许的最大连接数properties.setProperty("org.quartz.dataSource.HandsomeDB.maxConnections", "10");// 为 "HandsomeDB" 数据源设置一个用于测试连接是否可用的 SQL 查询语句properties.setProperty("org.quartz.dataSource.HandsomeDB.validationQuery", "select 1");// 返回创建好的 Quartz 的配置属性 Properties 实例return properties;}
}

在以上示例代码中,我们通过@Configuration注解标记了QuartzConfig类,并在其中进行SchedulerFactoryBean的配置。具体包括:

配置数据源dataSource,用于SchedulerFactoryBean连接数据库。
创建schedulerFactoryBean Bean实例,并设置相关属性,例如调度器名称、线程池、自动启动等,最后返回schedulerFactoryBean。
创建schedulerThreadPool Bean实例,用于执行定时任务的线程池配置。
配置quartzProperties,用于定义Quartz的属性,例如jobStore、schedulerName等。

需要注意的是,在实际生产环境中,我们可能还需要根据具体业务需求,对线程池、数据源等进行进一步的优化配置。

7.创建QuartzConfigService类,用于初始化调度器,并从数据库中读取定时任务配置信息,例如:

@Service
public class QuartzConfigService {@Autowiredprivate QuartzConfigRepository quartzConfigRepository;@Autowiredprivate SchedulerFactoryBean schedulerFactoryBean;// 初始化调度器,并从数据库中读取定时任务配置信息,创建对应的定时任务@PostConstructpublic void initScheduler() throws Exception {// 获取调度器实例Scheduler scheduler = schedulerFactoryBean.getScheduler();// 查询数据库中所有的定时任务配置信息List<QuartzConfig> quartzConfigs = quartzConfigRepository.findAll();// 遍历定时任务配置信息列表,为每个定时任务创建JobDetail和Trigger对象,并添加到调度器中for (QuartzConfig config : quartzConfigs) {// 创建一个JobDetail对象,用于描述Job实现类及其他一些静态信息JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity(config.getName(), config.getGroup()) // 定义任务名称和分组.usingJobData("param1", "value1").build();// 创建一个Trigger对象,用于定义周期性执行的时间规则等CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(config.getName(), config.getGroup()) // 定义任务名称和分组.withSchedule(CronScheduleBuilder.cronSchedule(config.getCronExpression())) // 定义Cron表达式.usingJobData("param2", "value2").build();// 将JobDetail和Trigger关联到调度器中,实现任务的调度scheduler.scheduleJob(jobDetail, trigger);}// 启动调度器scheduler.start();}// 新增定时任务配置 不影响原来的定时任务public void addQuartzConfig(QuartzConfig config) throws Exception {// 保存定时任务配置信息到数据库quartzConfigRepository.save(config);// 获取调度器实例Scheduler scheduler = schedulerFactoryBean.getScheduler();// 创建一个JobDetail对象,用于描述Job实现类及其他一些静态信息JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity(config.getName(), config.getGroup()) // 定义任务名称和分组.build();// 创建一个Trigger对象,用于定义周期性执行的时间规则等CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(config.getName(), config.getGroup()) // 定义任务名称和分组.withSchedule(CronScheduleBuilder.cronSchedule(config.getCronExpression())) // 定义Cron表达式.build();// 将JobDetail和Trigger关联到调度器中,实现任务的调度scheduler.scheduleJob(jobDetail, trigger);}
}

在以上示例代码中,我们通过@PostConstruct注解标记的initScheduler()方法,在Spring容器初始化完成后自动执行,实现从数据库中读取定时任务配置信息,并创建对应的JobDetail和Trigger对象,添加到调度器中,最后启动调度器,实现自动运行定时任务的功能。addQuartzConfig方法实现新增定时任务配置。

需要注意的是,在实际生产环境中,我们可能还需要根据具体业务需求,对定时任务的配置信息进行更新、删除等操作,因此需要在QuartzConfigService中添加相应的方法来实现这些功能。