为了账号安全,请及时绑定邮箱和手机立即绑定

使用石英调度程序在春季启动中进行动态作业调度

使用石英调度程序在春季启动中进行动态作业调度

Smart猫小萌 2022-09-01 16:48:43
我想根据用户从 UI 提供的计划配置动态计划作业。当用户从 UI 保存新的计划配置时,该进程必须使用新的计划参数调用新作业。可以有 n 个这样的配置来执行相同的作业。Spring支持作业细节和触发器的实现,如下所示。定义作业详细信息:@Beanpublic JobDetail jobDetail() {    return JobBuilder.newJob().ofType(SampleJob.class)      .storeDurably()      .withIdentity("Qrtz_Job_Detail")        .withDescription("Invoke Sample Job service...")      .build();}定义触发器:@Beanpublic Trigger trigger(JobDetail job) {    return TriggerBuilder.newTrigger().forJob(job)      .withIdentity("Qrtz_Trigger")      .withDescription("Sample trigger")      .withSchedule(simpleSchedule().repeatForever().withIntervalInHours(1))      .build();}如何传递作业详细信息的参数,并根据用户提供的参数动态触发?
查看完整描述

2 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

最简单的方法是通过扩展SpringBeanJobFactorycreateJobInstance方法来进行一些配置。然后你需要定义 SchedulerFactoryBean,最后定义你的 Scheduler@Override

@Configuration

public class SchedulerConfiguration {


    public class AutowireCapableBeanJobFactory extends SpringBeanJobFactory {


        private final AutowireCapableBeanFactory beanFactory;


        @Autowired

        public AutowireCapableBeanJobFactory(AutowireCapableBeanFactory beanFactory) {

            Assert.notNull(beanFactory, "Bean factory must not be null");

            this.beanFactory = beanFactory;

        }


        @Override

        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {

            Object jobInstance = super.createJobInstance(bundle);

            this.beanFactory.autowireBean(jobInstance);

            this.beanFactory.initializeBean(jobInstance, null);

            return jobInstance;

        }

    }


    @Bean

    public SchedulerFactoryBean schedulerFactory(ApplicationContext applicationContext) {

        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();

        schedulerFactoryBean.setJobFactory(new AutowireCapableBeanJobFactory(applicationContext.getAutowireCapableBeanFactory()));

        return schedulerFactoryBean;

    }


    @Bean

    public Scheduler scheduler(ApplicationContext applicationContext) throws SchedulerException {

        Scheduler scheduler = schedulerFactory(applicationContext).getScheduler();

        scheduler.start();

        return scheduler;

    }

}

然后,在应用程序中的任意位置(例如在 RestController 中),您可以访问调度程序并计划新作业:


@RestController

public class ScheduleController {


    @Autowired

    private Scheduler scheduler;


    @GetMapping(value = "/schedule/{detail}/{desc}")

    public String scheduleJob(@PathVariable(value = "detail") String detail, @PathVariable(value = "desc") String desc) throws SchedulerException {

        JobDetail job = newJob(detail, desc);

        return scheduler.scheduleJob(job, trigger(job)).toString();

    }


    private JobDetail newJob(String identity, String description) {

        return JobBuilder.newJob().ofType(SimpleJob.class).storeDurably()

                .withIdentity(JobKey.jobKey(identity))

                .withDescription(description)

                .build();

    }


    private SimpleTrigger trigger(JobDetail jobDetail) {

        return TriggerBuilder.newTrigger().forJob(jobDetail)

                .withIdentity(jobDetail.getKey().getName(), jobDetail.getKey().getGroup())

                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1))

                .build();

    }

}

您可以从您的 - 查看文档控制所有计划(暂停,停止,重新启动,删除等)Scheduler




查看完整回答
反对 回复 2022-09-01
?
慕森王

TA贡献1777条经验 获得超3个赞

这就是 JobDataMap 参数的用途。您可以使用这些参数将任意参数传递给作业和触发器。通常建议使用 String 参数值以避免各种序列化问题。JobDataMap API 提供了辅助方法,您可以使用这些方法将字符串值的 JobDataMap 参数值转换为各种基本 Java 对象(整数、长整型、双精度型、布尔值等)。

请注意,在作业详细信息级别上指定的 JobDataMap 参数可以在触发器级别被覆盖。在 JobDetail 级别,通常指定应用于所有作业执行的常用参数和/或默认值,并覆盖这些默认值和/或在触发器级别添加新参数。

有关详细信息,请参阅Quartz Javadoc:

JobBuilder.html#usingJobData

TriggerBuilder.html#usingJobData

作业数据地图.html


查看完整回答
反对 回复 2022-09-01
  • 2 回答
  • 0 关注
  • 107 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号