当前位置: 首页 > news >正文

spring-boot-starter-quartz 自动化配置解析

版本

spring-boot:3.3.4

源码解析

依赖包 spring-boot-starter-quartz 的作用为引入相关依赖:

  1. spring-boot-starter
  2. spring-context-support
  3. spring-tx
  4. 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");  }  }  }
}
http://www.lryc.cn/news/425603.html

相关文章:

  • DM8 数据库查询版本号以及授权到期时间SQL
  • 算法【Java】—— 双指针算法
  • 【Python快速入门和实践013】Python常用脚本-目标检测之按照类别数量划分数据集
  • C++ Primer 总结索引 | 第十八章:用于大型程序的工具
  • Python实现GAN(生成对抗网络)图像修复算法
  • java语言中的websocket
  • ASP.NET在线交流论坛管理系统
  • 【Kubernetes】身份认证与鉴权
  • 数据集与数据库:有什么区别?
  • BurpSuite
  • NetApp数据恢复—NetApp存储误删除文件如何恢复数据?
  • 基于springboot的医药管理系统
  • Android中的EventBus的用法
  • 梧桐数据库(WuTongDB):数据库在数据处理中是如何利用缓存机制的
  • C语言-数据类型
  • 左值引用、右值引用、移动构造
  • tekton通过ceph挂载node_modules的时候报错failed to execute command: copying dir: symlink
  • Xil_DCacheFlushRange的用法
  • k8s使用subpathexpr和hostpath分pod名字持久化日志
  • FChen的408学习日记--三次握手和四次握手
  • Unity技巧:轻松实现鼠标悬停文本时的动态变色效果
  • 谷歌账号活动异常,或者申诉回来以后需要手机验证的原因,以及验证手机号的错误操作和正确操作
  • System V IPC奥秘:解锁共享内存、消息队列与信号量的高效通信之路
  • 怎么将pdf转为ppt文件?pdf转ppt的8个方法
  • 【Datawhale AI夏令营第四期】 魔搭-大模型应用开发方向笔记 Task03 大咖项目分享 人话八股文Bakwaan_Buddy项目开发尝试
  • 如何在wordpress当中使用插件WP Coder(将html、css、javascript应用到wordpress上)
  • ActiveMQ、RabbitMQ、Kafka、RocketMQ在消息回溯、消息堆积+持久化、消息追踪、消息过滤的区别
  • 使用ITextRenderer导出PDF后无法打开问题,提示‘无法打开此文件‘
  • STL必须掌握的几大常见算法
  • HAproxy 七层负载均衡调度器详解及配置