spring-boot-starter-quartz 自动化配置解析
版本
spring-boot:3.3.4
源码解析
依赖包 spring-boot-starter-quartz 的作用为引入相关依赖:
- spring-boot-starter
- spring-context-support
- spring-tx
- quartz
自动化配置类
依赖:spring-boot-autoconfigure:3.2.4
文件:org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration
// 因为需要使用datasource,在数据源配置之后执行配置
@AutoConfiguration(after = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, LiquibaseAutoConfiguration.class, FlywayAutoConfiguration.class })
// 自动配置条件:
// 1. Scheduler.class - quartz 调度器
// 2. SchedulerFactoryBean.class - spring-context-support SPRING上下文工具
// 3. PlatformTransactionManager.class - spring-tx SPRING事务
@ConditionalOnClass({ Scheduler.class, SchedulerFactoryBean.class, PlatformTransactionManager.class })
// 启用spring.quartz配置项
@EnableConfigurationProperties(QuartzProperties.class)
public class QuartzAutoConfiguration {// 注册quartz调度器工厂@Bean @ConditionalOnMissingBean public SchedulerFactoryBean quartzScheduler(QuartzProperties properties, ObjectProvider<SchedulerFactoryBeanCustomizer> customizers,ObjectProvider<JobDetail> jobDetails, Map<String, Calendar> calendars,ObjectProvider<Trigger> triggers,ApplicationContext applicationContext) { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); // job工厂,此工厂可以构造job bean 并实现依赖注入,和 jobData 注入SpringBeanJobFactory jobFactory = new SpringBeanJobFactory(); // 设置应用上下文,SchedulerFactoryBean需要使用 applicationContext.getAutowireCapableBeanFactory().createBean实现job bean构造和依赖注入jobFactory.setApplicationContext(applicationContext); schedulerFactoryBean.setJobFactory(jobFactory); // 配置名称if (properties.getSchedulerName() != null) { schedulerFactoryBean.setSchedulerName(properties.getSchedulerName()); } // 配置是否自动启动schedulerFactoryBean.setAutoStartup(properties.isAutoStartup()); // 配置启动延迟时间schedulerFactoryBean.setStartupDelay((int) properties.getStartupDelay().getSeconds()); // 配置关闭调度器时是否等待JOB执行完毕schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(properties.isWaitForJobsToCompleteOnShutdown()); // 配置是否覆盖已存在的JOB,标识为true后,添加相同key的作业/触发器默认将直接覆盖原有的作业/触发器。schedulerFactoryBean.setOverwriteExistingJobs(properties.isOverwriteExistingJobs()); // 配置其他属性 if (!properties.getProperties().isEmpty()) { schedulerFactoryBean.setQuartzProperties(asProperties(properties.getProperties())); }// 注册jobschedulerFactoryBean.setJobDetails(jobDetails.orderedStream().toArray(JobDetail[]::new)); // 注册日历schedulerFactoryBean.setCalendars(calendars); // 注册触发器schedulerFactoryBean.setTriggers(triggers.orderedStream().toArray(Trigger[]::new)); // 注册客制化器customizers.orderedStream().forEach((customizer) -> customizer.customize(schedulerFactoryBean)); return schedulerFactoryBean; }...// 配置持久化 JDBC存储@Configuration(proxyBeanMethods = false) // 条件1:存在单一的数据源bean@ConditionalOnSingleCandidate(DataSource.class) // 条件2:配置属性 spring.quartz.job-store-type=jdbc@ConditionalOnProperty(prefix = "spring.quartz", name = "job-store-type", havingValue = "jdbc") // 导入数据库初始化配置器@Import(DatabaseInitializationDependencyConfigurer.class) protected static class JdbcStoreTypeConfiguration { // 配置数据源的调度器工厂客制化器@Bean @Order(0) public SchedulerFactoryBeanCustomizer dataSourceCustomizer(QuartzProperties properties,DataSource dataSource, @QuartzDataSource ObjectProvider<DataSource> quartzDataSource, ObjectProvider<PlatformTransactionManager> transactionManager, @QuartzTransactionManager ObjectProvider<PlatformTransactionManager> quartzTransactionManager) { return (schedulerFactoryBean) -> { // 配置数据源DataSource dataSourceToUse = getDataSource(dataSource, quartzDataSource); schedulerFactoryBean.setDataSource(dataSourceToUse); // 配置事务管理器PlatformTransactionManager txManager = getTransactionManager(transactionManager, quartzTransactionManager); if (txManager != null) { schedulerFactoryBean.setTransactionManager(txManager); } }; } // 获取数据源,优先使用 QuartzDataSource 注解的数据源,否则使用应用的主数据源(Primary)private DataSource getDataSource(DataSource dataSource, ObjectProvider<DataSource> quartzDataSource) { DataSource dataSourceIfAvailable = quartzDataSource.getIfAvailable(); return (dataSourceIfAvailable != null) ? dataSourceIfAvailable : dataSource; } // 获取事务管理器,优先使用 QuartzTransactionManager 注解的事务管理器,否则使用应用的事务管理器private PlatformTransactionManager getTransactionManager( ObjectProvider<PlatformTransactionManager> transactionManager, ObjectProvider<PlatformTransactionManager> quartzTransactionManager) { PlatformTransactionManager transactionManagerIfAvailable = quartzTransactionManager.getIfAvailable(); return (transactionManagerIfAvailable != null) ? transactionManagerIfAvailable : transactionManager.getIfUnique(); } // 注册数据库表初始化器,可通过配置属性 spring.quartz.jdbc.initialize-schema 指定是否初始化数据库// 1. 默认值 EMBEDDED ,标识只初始化内置数据库// 2. 如果需要初始化外部数据库的数据源,可配置为ALWAYS,则总是会执行初始化脚本// 3. 初始化完成后,可配置为NEVER,则不会在每次启动时初始化数据// 可通过 配置属性 spring.quartz.jdbc.schema 指定初始化脚本位置 ,默认使用位于 classpath:org/quartz/impl/jdbcjobstore/tables_@@platform@@.sql 的脚本// schema中的占位符@@platform@@ 会被替换为实际数据源对应的数据库平台类型@Bean // 条件1:没有注册其他初始化器@ConditionalOnMissingBean(QuartzDataSourceScriptDatabaseInitializer.class) // 条件2:检查是否配置属性 spring.quartz.jdbc.initialize-schema@Conditional(OnQuartzDatasourceInitializationCondition.class) public QuartzDataSourceScriptDatabaseInitializer quartzDataSourceScriptDatabaseInitializer( DataSource dataSource, @QuartzDataSource ObjectProvider<DataSource> quartzDataSource, QuartzProperties properties) { DataSource dataSourceToUse = getDataSource(dataSource, quartzDataSource); return new QuartzDataSourceScriptDatabaseInitializer(dataSourceToUse, properties); } static class OnQuartzDatasourceInitializationCondition extends OnDatabaseInitializationCondition { OnQuartzDatasourceInitializationCondition() { super("Quartz", "spring.quartz.jdbc.initialize-schema"); } } }
}