如何以动态方式创建 Spring Bean。使用 Quartz SchedulerFactoryBean

2024-04-25

我有一个QuartzJobConfig我注册的班级Spring-Quartz-Beans.

我按照指示SchedulerFactoryBean, JobDetailFactoryBean and CronTriggerFactoryBean.

我的作业配置在yaml应用程序外部的文件。意味着我必须在应用程序启动时动态创建 Bean。

我的配置:

channelPartnerConfiguration:
  channelPartners:
  - code: Job1
    jobConfigs:
    - schedule: 0 * * ? * MON-FRI
      name: Job1 daily
      hotel: false
      allotment: true
      enabled: true
    - schedule: 30 * * ? * MON-FRI
      name: Job2 weekly
      hotel: true
      allotment: false
      enabled: true
    ...

我的配置类:

@Configuration
public class QuartzJobConfig implements IJobClass{

    @Autowired 
    ChannelPartnerProperties channelPartnerProperties;

    @Autowired
    private ApplicationContext applicationContext;

    @Bean
    public SchedulerFactoryBean quartzScheduler() {
        SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();

        quartzScheduler.setOverwriteExistingJobs(true);
        quartzScheduler.setSchedulerName("-scheduler");

        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        quartzScheduler.setJobFactory(jobFactory);

        // point 1
        List<Trigger> triggers = new ArrayList<>();
        for(ChannelPartner ch : channelPartnerProperties.getChannelPartners()){
            for(JobConfig jobConfig : ch.getJobConfigs()){
                triggers.add(jobTrigger(ch, jobConfig).getObject());
            }
        }
        quartzScheduler.setTriggers(triggers.stream().toArray(Trigger[]::new));

        return quartzScheduler;
    }

    @Bean
    public JobDetailFactoryBean jobBean(ChannelPartner ch, JobConfig jobConfig) {
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(findJobByConfig(jobConfig));
        jobDetailFactoryBean.setGroup("mainGroup");
        jobDetailFactoryBean.setName(jobConfig.getName());
        jobDetailFactoryBean.setBeanName(jobConfig.getName());
        jobDetailFactoryBean.getJobDataMap().put("channelPartner", ch);
        return jobDetailFactoryBean;
    }

    @Bean
    public CronTriggerFactoryBean jobTrigger(ChannelPartner ch, JobConfig jobConfig) {
        CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
        cronTriggerFactoryBean.setJobDetail(jobBean(ch, jobConfig).getObject());
        cronTriggerFactoryBean.setCronExpression(jobConfig.getSchedule());
        cronTriggerFactoryBean.setGroup("mainGroup");
        return cronTriggerFactoryBean;
    }

    @Override
    public Class<? extends Job> findJobByConfig(JobConfig jobConfig) {
        if(isAllotmentJob(jobConfig) && isHotelJob(jobConfig)){
            return HotelAndAllotmentJob.class;
        }
        if(isAllotmentJob(jobConfig)){
            return AllotmentJob.class;
        }
        if(isHotelJob(jobConfig)){
            return HotelJob.class;
        }
        return HotelAndAllotmentJob.class;
    }

    private boolean isAllotmentJob(JobConfig jobConfig){
        return jobConfig.isAllotment();
    }

    private boolean isHotelJob(JobConfig jobConfig) {
        return jobConfig.isHotel();
    }

}

我的问题是迭代(第 1 点)内 Bean 的创建只完成了一次。第一次迭代后,它不会进入jobTrigger(ch, jobConfig)方法不再了。 (如果我是对的,由于豆子的名字,或多或少很清楚)

我在想什么,因为我使用Quartz factories春天的jobDetailFactoryBean.setBeanName()方法用于创建更多具有不同名称的bean。

不知道如何解决这个问题。代码正在运行,第一个创建的作业正在正确执行。但我需要更多的工作。

如何以动态方式创建不同的工作?


Edit:

我的完整配置类:

@Configuration
@ConfigurationProperties(prefix = "channelPartnerConfiguration", locations = "classpath:customer/channelPartnerConfiguration.yml")
public class ChannelPartnerProperties {

    @Autowired
    private List<ChannelPartner> channelPartners;

    public List<ChannelPartner> getChannelPartners() {
        return channelPartners;
    }

    public void setChannelPartners(List<ChannelPartner> channelPartners) {
        this.channelPartners = channelPartners;
    }
}

@Configuration
public class ChannelPartner {

    private String code;
    private String contracts;
    private Boolean includeSpecialContracts;
    private String touroperatorCode = "EUTO";

    @Autowired
    private PublishConfig publishConfig;

    @Autowired
    private BackupConfig backupConfig;

    @Autowired
    private List<JobConfig> jobConfigs;
    //getter/setter

@Configuration
public class JobConfig {

    private String schedule;
    private boolean hotelEDF;
    private boolean allotmentEDF;
    private boolean enabled;
    private String name;
    //getter/setter

Added 项目到github https://github.com/Pkurz/Quartz为了更好地理解问题


您的列表将包含 null 值的原因是因为您调用的 getObject 方法应该返回 CronTrigger,该方法仅在启动 spring 上下文后由 spring 调用的 afterPropertiesSet 方法中启动。您可以在 CronTriggerFactoryBean 上手动调用此方法,这将允许您将其作为私有方法。

    // Just to clarify, no annotations here
    private CronTriggerFactoryBean jobTrigger(ChannelPartner ch, JobConfig jobConfig) throws ParseException {
        CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
        cronTriggerFactoryBean.setJobDetail(jobBean(ch, jobConfig).getObject());
        cronTriggerFactoryBean.setCronExpression(jobConfig.getSchedule());
        cronTriggerFactoryBean.setGroup("mainGroup");
        cronTriggerFactoryBean.setBeanName(jobConfig.getName() + "Trigger");
        cronTriggerFactoryBean.afterPropertiesSet();
        return cronTriggerFactoryBean;
    }

我确信还有很多其他方法可以做到这一点,正如您自己提到的,您为此做了一个解决方法,如果这不是您想要或需要的,我可以检查更多,如果我能找到更好的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何以动态方式创建 Spring Bean。使用 Quartz SchedulerFactoryBean 的相关文章

  • 禁用特定的 ServletContextListener 以防止在 tomcat 上启动

    我的项目正在使用spring boot with webflux tomcat 我有一个内部库类 它是ServletContextListener WebListener public class DevIoServletContextLi
  • Glide:如何使用 Glide v4 调整 gif 大小并将其另存为文件?

    我想调整 gif 文件的大小并保存它 我尝试使用一些建议的方法 但这些方法给出了错误 后来我知道有些方法在 Glide 中已被弃用v4 byte bytes Glide with context asGif load url toBytes
  • 如何在angularjs中读取pdf流

    I got the following PDF stream from a server 如何在 AngularJS 中读取这个流 我尝试使用以下代码在新窗口中将其作为 PDF 文件打开 success function data wind
  • Servlet 包含 Tomcat 中的 HTTP 标头

    我有一个 servlet 它的请求调度程序包含另一个 servlet 包含的 servlet 设置了我想在包括小服务程序 因此 我在 include 方法中传入一个自定义 HTTPResponse 对象 该对象捕获来自 servlet 的所
  • Java 中修剪字符串的可能前缀

    I have String str 我想从中提取不包括可能的前缀的子字符串 abc 我想到的第一个解决方案是 if str startsWith abc return str substring abc length return str
  • Spring Batch - 读取多行日志消息

    我面临一个问题 在配置了 Spring 集成的 Spring Batch 应用程序中将多行日志消息读取为单个消息 该应用程序必须将多行日志消息 示例异常堆栈跟踪 读取为单个消息 稍后它必须处理并对消息进行分类以进一步建立索引 每行都由其时间
  • 如何将跨源资源共享与 Spring MVC 4.0.0 RESTful Webservice 集成

    我有一个简单的 Web 服务返回JSON data The 用户等级 com bargadss SpringService Domain 是个POJO类包含 用户 ID 名字 姓氏 电子邮件 The 用户服务类 com bargadss S
  • Selenium 2:中断页面加载

    我在使用 FirefoxDriver 使用 Selenium 2 0b3 Java API 单击按钮时遇到问题 单击该按钮会将表单发送到网络服务器 然后浏览器会因表单提交而进入新页面 当使用 element click 单击某个元素时 se
  • 在 JSON 转换为 CSV 期间保持 JSON 键的顺序

    我正在使用此处提供的 JSON 库http www json org java index html http www json org java index html为了将 json 字符串转换为 CSV 但我遇到的问题是 转换后键的顺序
  • 在 Android 谷歌地图中绘制 4K 折线

    我现在正在开发一个适用于 Android 设备的应用程序 主要功能是在地图上绘制折线以显示城市中每条街道的交通情况 不幸的是 当我绘制大约 3K 折线时 数量会根据屏幕尺寸和缩放级别而减少 我的地图变得非常慢 我没有提及绘制所有线条的时间
  • Java TreeMap时间复杂度-lowerKey

    时间复杂度是多少lowerKey Java实现中的操作TreeMap 我认为它是 log n 但我在文档中找不到它 更基本操作的复杂性已有详细记录 此实现提供了有保证的 log n 时间成本 containsKey 获取 放置和删除操作 顺
  • 使用java服务中的Zxing库从单个图像文件中读取多个条形码

    您好 我已经创建了一个java服务 用于从此处的图像中读取条形码 我使用Zxing库来解码此处的文本 挑战是 如果一个带有单个条形码的文件工作正常 如果有多个条形码 它会产生不相关的结果 我在下面给出了我的代码 pom xml
  • 什么是样板代码、热点代码和热点?

    我知道这些术语是在性能实现 优化的背景下使用的 最近一直在研究这个问题 并尝试过搜索 但没有得到任何例子 清楚地阐述 描述这些概念以及在现实世界开发场景中实现这些问题 概念 有人可以彻底解释这些术语 示例场景以及可能使用这些概念和术语的地方
  • Spring JPA (Hibernate) Entity Manager 何时将连接返回到连接池?

    在我的 java 进程中 我使用以下 spring 配置连接到 MySql Configuration EnableTransactionManagement PropertySources PropertySource classpath
  • 遍历多行字符串

    我得到一些数据 def data some useless text n even more n finally interesting text 我怎样才能得到其中 有趣的部分 所以基本上所有行都不是以 开头的 Groovy 的一种选择是
  • Spring Boot MultipartFile上传getOriginalFileName根据浏览器不同而不同

    我使用的是 spring boot 1 5 7 RELEASE 版本 我使用以下方法上传文件 Autowired private MyService mySerice RequestMapping value uploadFile meth
  • OutputStream 到 DB2 数据库表的 BLOB 列

    在 DB2 数据库中 我有下表 CREATE TABLE MyTestTable MYPATH VARCHAR 512 NOT NULL MYDATA BLOB CONSTRAINT MYTESTTABLE PK PRIMARY KEY M
  • Spring Data 中 IQueryable 的等效项

    我习惯了 Net 和 LINQtoEntities 尤其是 IQueryable 部分 它允许在获取结果之前通过不同的函数传送请求 Spring数据中是否存在类似的东西 或者任何其他 java ORM 我希望能够做的基本示例 private
  • 扫描图像到可读文本

    我想知道是否有一种方法可以通过编写代码来将带有文本的扫描图像转换为可读文本 那可能吗 OCRTools http www ocrtools com是我用于 net 的 对于Java 我用过Aspire http asprise com pr
  • Android:如何获取小数点后的两位数?不想截断值

    如何获取小数点后仅两位数的双精度值 例如 如果 a 190253 80846153846 那么结果值应该像 a 190253 80 尝试 我尝试过这个 public static DecimalFormat twoDForm new Dec

随机推荐

  • 为什么Python中set的大小可以比dict大?

    为什么a的大小是set比一个大dict s set d for i in range 20 s add i d i 1 print f i 1 s sizeof d sizeof Output 17 712 624 18 712 624 1
  • 如何在 Google Dataproc 集群中安装 python 包

    创建并运行集群后 是否可以在 Google Dataproc 集群中安装 python 包 我尝试使用 pip install xxxxxxx 在主命令行中 但它似乎不起作用 Google的Dataproc文档没有提及这种情况 创建集群后
  • 按组添加ID列[重复]

    这个问题在这里已经有答案了 我想根据两列纬度和经度在 R 中创建一个唯一 ID 以便重复的位置具有相同的集群 ID 例如 LAT LONG Cluster ID 13 5330 15 4180 1 13 5330 15 4180 1 13
  • MemoryCache 的大小设置意味着什么?

    在控制器类中 我有 using Microsoft Extensions Caching Memory private IMemoryCache cache private readonly MemoryCacheEntryOptions
  • PHP 创建日期范围

    以这种格式的日期开始 2011 05 01 09 00 00 如何创建一个包含一年中所有工作日 因此排除所有周六和周日 的所有办公时间 09 00 到 17 00 的数组 我想要达到的是这样的 2011 05 01 09 00 00 201
  • 重置远程跟踪分支

    如何将远程跟踪分支的分支指针重置为其之前的提交之一 这样看起来我没有拉动 类似于本地分支的硬重置 您可以使用以下命令设置对任何其他提交的引用 git update ref refs remotes origin master
  • 如何从 VB-6 旧应用程序中启动屏幕键盘程序

    我正在尝试从 Windows 10 32 或 Windows 10 64 位计算机上的 VB 6 应用程序中 shell osk exe 过去我们只是简单地使用 Private Sub Command1 Click Dim strTemp
  • 您能否将 TeamCity“工件”配置为重新检入源代码管理?

    我希望将 TeamCity Artifacts 重新签入源代码管理 我以前使用过 TFS Integrator 所以我习惯了它的方法 通过配置 它可以将输出构建签入源代码管理 然后 当人们进行 get 操作时 他们将收到这些文物 或者是否有
  • 指定共享对象(共享库)的名称

    Go 编译器为共享对象生成的名称是错误的 例子 go install buildmode shared linkshared github com apache thrift lib go thrift code google com p
  • Windows 安装程序和安装应用程序合并到一个文件中?

    我使用 Visual Studio 在 C 中编写了一个应用程序 我创建了一个项目设置文件 该文件在我的调试中为我创建了文件 Windows Installer 和安装应用程序都是必需的 但我想将它们合并为一个 就像当您下载应用程序时 安装
  • java中删除文件中的一行

    好的 所以我尝试使用 java lang String 从文本文件中删除行 目前我这样做的方式是跟踪行号并输入索引 索引是我要删除的行 因此 每次读取新的数据行时 我都会增加行数 现在 当我达到相同索引的行数时 我不会将数据写入临时文件 现
  • asp.net mvc相当于rails回调before_save

    您好 我正在寻找一个 ASP NET MVC 回调 以便在保存模型之前获取详细数据 Rails 中有 before save Thanks 如果您正在使用实体框架 您的标签表明 那么这个 StackOverflow 帖子 https sta
  • Async CTP 可以与可移植库一起使用吗

    我想看看异步 CTP 是否带有可移植类库 不可以 异步 CTP 对于桌面 电话 Silverlight 4 和 Silverlight 5 有不同的 dll 希望在不久的将来 所有这些平台都将原生支持任务 和异步 然后可移植类库将能够使用异
  • 依赖注入和项目参考[重复]

    这个问题在这里已经有答案了 我正在尝试了解 DI 以便更好地了解 IoC 以及其他好处 在 DI 之前 我有一个项目 其中包含一个 UI 项目 MVC 一个 BusinessLogic 项目和一个 DataAccess 项目 我还有一个 S
  • 当 Django 在 postgresql 中使用可序列化事务隔离级别时,哪些具体异常代表序列化失败?

    有时 对于 Django 中的数据库操作 需要使用比默认 已提交读 更高的隔离级别 文档警告 https docs djangoproject com en 1 11 ref databases isolation level that 在
  • StringBuilder 在 C# 中的性能?

    我有一个StringBuilder对象 我在其中添加一些字符串 如下所示 我想知道哪种方法更好 第一个是 StringBuilder sb new StringBuilder sb Append Hello How are you 第二个是
  • 使用 XSLT 转换 XML 并保留 Unicode 字符

    我的 XSLT 转换已经成功了几个月 直到我遇到带有 Unicode 字符 很可能是表情符号 的 XML 文件 我需要保留 Unicode 但 XSLT 正在将其转换为 HTML 实体 我认为将编码设置为 UTF 8 可以解决我的问题 但我
  • 为什么 copyTo(... PASTE_VALUES) 在宏中间不起作用?

    我长期使用的电子表格技术之一是就地复制 粘贴特殊值 C PSV 使用公式生成我感兴趣的值后 I C PSV 然后可以删除源数据 所以我写了一个使用这种技术的宏 但单元格最终是空的 但如果我将宏分成两个 在 C PSV 之前结束第一个宏 那么
  • 不同种类的ReaderT?

    冒着成为一个XY问题 https en wikipedia org wiki XY problem 是否有可能有一个ReaderT与不同的环境 我正在尝试类似 type AppM perms ReaderT perms IO 但是编译器抱怨
  • 如何以动态方式创建 Spring Bean。使用 Quartz SchedulerFactoryBean

    我有一个QuartzJobConfig我注册的班级Spring Quartz Beans 我按照指示SchedulerFactoryBean JobDetailFactoryBean and CronTriggerFactoryBean 我