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"); } } }
}
相关文章:
spring-boot-starter-quartz 自动化配置解析
版本 spring-boot:3.3.4 源码解析 依赖包 spring-boot-starter-quartz 的作用为引入相关依赖: spring-boot-starterspring-context-supportspring-txquartz 自动化配置类 依赖:spring-boot-autoconfigure:3.2.4 文件:org.springframewo…...
DM8 数据库查询版本号以及授权到期时间SQL
1.查看操作系统信息 [root@localhost ~]# cat /etc/.kyinfo [dist] name=Kylin milestone=Server-V10-GFB-Release-ZF9_01-2204-Build03 arch=arm64 beta=False time=2023-01-09 11:04:36 dist_id=Kylin-Server-V10-GFB-Release-ZF9_01-2204-Build03-arm64-2023-01-09 11:04:…...

算法【Java】—— 双指针算法
双指针算法 常见的双指针有对撞指针,快慢指针以及前后指针(这个前后指针是指两个指针都是从从一个方向出发,去往另一个方法,也可以认为是小学学习过的两车并行,我也会叫做同向指针),在前后指针…...

【Python快速入门和实践013】Python常用脚本-目标检测之按照类别数量划分数据集
一、功能介绍 这段代码实现了从给定的图像和标签文件夹中分割数据集为训练集、验证集和测试集的功能。以下是代码功能的总结: 创建目标文件夹结构: 在指定的根目录(dataset_root)下创建images和labels两个文件夹。在这两个文件夹下…...

C++ Primer 总结索引 | 第十八章:用于大型程序的工具
1、大规模应用程序的特殊要求包括: 在独立开发的子系统之间 协同处理错误的能力使用各种库(可能包含独立开发的库)进行 协同开发的能力对比较复杂的应用 概念建模的能力 对应 异常处理、命名空间和多重继承 1、异常处理 1、异常处理机制 …...
Python实现GAN(生成对抗网络)图像修复算法
目录 1. GAN简介与图像修复2. PyTorch和CUDA简介3. 数据加载与预处理3.1 安装依赖3.2 数据加载3.3 数据遮挡4. 构建GAN图像修复模型4.1 生成器4.2 判别器5. 训练GAN模型5.1 损失函数与优化器5.2 训练循环6. 测7. 实现GUI进行图像修复8. 总结与扩展扩展方向:1. GAN简介与图像修…...
java语言中的websocket
你好!我是TensGPT,一个由TensGPT团队开发的AI助手。我可以帮助你了解和使用Java语言中的WebSocket。如果你有任何问题或需要示例代码,请告诉我。 ### 什么是WebSocket? WebSocket是一种在单个TCP连接上进行全双工通信的协议。它被…...

ASP.NET在线交流论坛管理系统
ASP.NET在线交流论坛管理系统 说明文档 运行前附加数据库.mdf(或sql生成数据库) 主要技术: 基于asp.net架构和sql server数据库 用户功能有个人信息管理 帖了信息管理 意见反馈信息管理 点赞管理 收藏管理 后台管理员可以进行用户管理 …...

【Kubernetes】身份认证与鉴权
一,认证 所有 Kubernetes 集群有两类用户:由Kubernetes管理的ServiceAccounts(服务账户)和(Users Accounts)普通账户。 两种账户的区别: 普通帐户是针对(人)用户的,服务账户针对Pod进程普通帐户是全局性。在集群所有namespaces…...

数据集与数据库:有什么区别?
数据集和数据库是我们在处理数据时经常听到的两个常用词。虽然它们听起来很相似,但它们具有不同的特征并用于不同的用途。本文深入探讨数据集和数据库之间的主要区别,探索了它们的结构、数据类型和各种其他功能,以帮助您做出明智的决定&#…...

BurpSuite
如果只能用一个Web渗透工具,我选BurpSuite。 Web应用程序(Web Application) 不同于传统的静态网站所有程序的特点是接收、处理用户输入并返回结果服务器端是个程序,需要程序代码实现业务功能(java、php、asp.nse&…...

NetApp数据恢复—NetApp存储误删除文件如何恢复数据?
NetApp数据恢复环境&故障: 某公司一台NetApp存储,该存储中有24块磁盘。 工作人员误删除了NetApp存储中一个文件夹,文件夹中有非常重要的数据。 数据恢复工程师在现场对该存储进行了初检。虽然这个文件夹被删除很长时间,但是根…...

基于springboot的医药管理系统
TOC springboot194基于springboot的医药管理系统 绪论 1.1 选题背景 当人们发现随着生产规模的不断扩大,人为计算方面才是一个巨大的短板,所以发明了各种计算设备,从结绳记事,到算筹,以及算盘,到如今的…...

Android中的EventBus的用法
1. EventBus简介 EventBus是一个优化了的事件发布/订阅模式实现的库,常用于Android程序组件间的通信。它可以简化不同组件之间的通信工作,避免复杂和耦合的依赖关系。EventBus通过事件驱动来降低代码耦合度,提高开发效率和代码清晰性。 2. …...
梧桐数据库(WuTongDB):数据库在数据处理中是如何利用缓存机制的
数据库在数据处理中利用缓存机制主要是为了提高数据访问速度和系统性能。缓存机制通过将频繁访问的数据存储在内存中,减少了对磁盘I/O操作的需求,从而提高了数据查询的效率。以下是数据库利用缓存机制的一些主要方式: 1. 查询缓存࿰…...

C语言-数据类型
在x64编译器平台下,C语言数据类型的取值范围主要取决于数据类型的大小(即字节数)以及它们是有符号的还是无符号的。以下是根据常见实现总结的x64平台下C语言数据类型的取值范围: 整数类型 浮点类型 指针类型 在x64编译器平台下…...
左值引用、右值引用、移动构造
1、为啥使用引用? // An highlighted block void function(string str) {... ... }看上面这段代码,如果不采用引用的方法,那么在函数被调用的时候,编译器会有一个参数赋值的过程,这就导致了内存和效率的浪费。 // An…...

tekton通过ceph挂载node_modules的时候报错failed to execute command: copying dir: symlink
分析: 如果ceph的mountPath和workingDir路径一致的话,就会报错。 解决:node_modules挂载到/workspace下,workingDir的代码mv到/workspace下进行构建。...
Xil_DCacheFlushRange的用法
概述: 当使用Zynq的PS (Processing System) 与PL (Programmable Logic) 进行通信时,特别是涉及到高速数据传输时,可能会遇到缓存一致性问题。这是因为处理器系统通常具有缓存机制来加快对常用数据的访问速度,但在某些情况下&…...
k8s使用subpathexpr和hostpath分pod名字持久化日志
在k8s中,服务日志除了标准输出,还有写入日志文件,若要对这些日志文件进行持久化存储,无论是通过网络文件存储还是hostpath,都会面临一个问题,多个pod会往同一个存储目录的同一个文件进行写入,导…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...

UE5 音效系统
一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类,将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix,将上述三个类翻入其中,通过它管理每个音乐…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
StarRocks 全面向量化执行引擎深度解析
StarRocks 全面向量化执行引擎深度解析 StarRocks 的向量化执行引擎是其高性能的核心设计,相比传统行式处理引擎(如MySQL),性能可提升 5-10倍。以下是分层拆解: 1. 向量化 vs 传统行式处理 维度行式处理向量化处理数…...
背包问题双雄:01 背包与完全背包详解(Java 实现)
一、背包问题概述 背包问题是动态规划领域的经典问题,其核心在于如何在有限容量的背包中选择物品,使得总价值最大化。根据物品选择规则的不同,主要分为两类: 01 背包:每件物品最多选 1 次(选或不选&#…...

【工具教程】多个条形码识别用条码内容对图片重命名,批量PDF条形码识别后用条码内容批量改名,使用教程及注意事项
一、条形码识别改名使用教程 打开软件并选择处理模式:打开软件后,根据要处理的文件类型,选择 “图片识别模式” 或 “PDF 识别模式”。如果是处理包含条形码的 PDF 文件,就选择 “PDF 识别模式”;若是处理图片文件&…...