当前位置: 首页 > 知识库问答 >
问题:

Spring石英触发程序作业

梁丘波
2023-03-14

我有一个Sprint Boot-Java8应用程序,它有一个quartz作业,我在启动时配置该作业并设置一个时间表。该作业按照计划自动运行,这与您对quartz作业的期望一样。然而,现在我希望能够允许用户通过点击前端上的一个按钮手动触发这些作业,而不会扰乱该作业的正常调度。这是我所有的相关档案。

quartz:
    fooCron: 0 0 1 * * ?
    fooGroup: foo-quartz-group
@Configuration
@ConfigurationProperties(prefix = "quartz")
public class QuartzConfig {
    private String fooCron;
    private String fooGroup;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Autowired
    private DataSource dataSource;

    @Bean
    public SchedulerFactoryBean quartzScheduler() {
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);

        Trigger[] triggers = {fooTrigger().getObject()};

        SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();
        quartzScheduler.setJobFactory(jobFactory);
        quartzScheduler.setTransactionManager(transactionManager);
        quartzScheduler.setDataSource(dataSource);
        quartzScheduler.setOverwriteExistingJobs(true);
        quartzScheduler.setSchedulerName("foo-scheduler");
        quartzScheduler.setQuartzProperties(quartzProperties());
        quartzScheduler.setTriggers(triggers);

        return quartzScheduler;
    }

    @Bean
    public CronTriggerFactoryBean fooTrigger() {
        CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
        cronTriggerFactoryBean.setJobDetail(fooJob().getObject());
        cronTriggerFactoryBean.setCronExpression(fooCron);
        cronTriggerFactoryBean.setGroup(fooGroup);
        return cronTriggerFactoryBean;
    }

    @Bean
    public JobDetailFactoryBean fooJob() {
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(FooJob.class);
        jobDetailFactoryBean.setGroup(fooGroup);
        jobDetailFactoryBean.setDurability(true);
        return jobDetailFactoryBean;
    }

    @Bean
    public Properties quartzProperties() {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("/quartz/quartz.properties"));
        Properties properties = null;
        try {
            propertiesFactoryBean.afterPropertiesSet();
            properties = propertiesFactoryBean.getObject();
        } catch (IOException e) {
        }

        return properties;
    }

    //setters
}
@Service
public class FooJob implements Job {
    private final FooRepository fooRepo; //This is a repository class annotated with @Repository.

    public FooJob(FooRepository fooRepo) {
        this.fooRepo = fooRepo;
    }

    @Override
    public void execute(final JobExecutionContext context) throws JobExecutionException {
        //do stuff
    }
}

QuartzController.java

@RestController
@RequestMapping("/quartz")
public class QuartzController {
    private SchedulerFactoryBean schedulerFactoryBean;
    private Scheduler scheduler;

    public DevopsController(final SchedulerFactoryBean quartzScheduler) {
        this.schedulerFactoryBean = quartzScheduler;
        scheduler = schedulerFactoryBean.getScheduler();
    }

    @PostMapping("/execute")
    public ResponseEntity executeJob() {
        HttpStatus status = OK;
        try {
            TriggerKey triggerKey = new TriggerKey("fooTrigger", "foo-quartz-group");
            Trigger trigger = scheduler.getTrigger(triggerKey);
            ScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).withRepeatCount(0);
            JobDetail jobDetail = scheduler.getJobDetail(trigger.getJobKey());
            Trigger newTrigger = TriggerBuilder.newTrigger()
                                               .forJob(jobDetail)
                                               .startNow()
                                               .withIdentity(triggerKey)
                                               .withSchedule(scheduleBuilder)
                                               .startAt(Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()))
                                               .build();
            //I have tried all 3 of the following lines
            scheduler.scheduleJob(jobDetail, new HashSet<>(Arrays.asList(trigger)), true);
            //scheduler.addJob(jobDetail, true);
            //scheduler.rescheduleJob(triggerKey, newTrigger);
        } catch (SchedulerException e) {
            status = BAD_REQUEST;
        }

        return new ResponseEntity<>(status);
    }
}

但每次运行应用程序并点击控制器的schedulejob方法时,都会在控制台中出现以下错误:

org.quartz.SchedulerException: Job instantiation failed
    at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:45)
    at org.quartz.core.JobRunShell.initialize(JobRunShell.java:127)
    at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:375)
Caused by: java.lang.InstantiationException: com.test.jobs.FooJob
    at java.lang.Class.newInstance(Class.java:427)
    at org.springframework.scheduling.quartz.AdaptableJobFactory.createJobInstance(AdaptableJobFactory.java:58)
    at org.springframework.scheduling.quartz.SpringBeanJobFactory.createJobInstance(SpringBeanJobFactory.java:74)
    at com.test.config.AutowiringSpringBeanJobFactory.createJobInstance(AutowiringSpringBeanJobFactory.java:27)
    at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:41)
    ... 2 common frames omitted
Caused by: java.lang.NoSuchMethodException: com.test.jobs.FooJob.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    ... 6 common frames omitted

我到底做错了什么?如何使此作业按计划自动运行,但也可根据手动请求执行

我正在使用sprint boot1.5.9.release和quartz2.2.1

共有1个答案

裴宜春
2023-03-14

正如@scary-wombat所说,您必须在foojob中添加一个无参数构造函数。您的方法的问题是,以这种方式无法获得fooRepository

public FooJob() {
}

您有2个选项

1)如果fooRepository有@respository注释,则可以向构造函数添加@autowired注释。

@Autowired
public FooJob(FooRepository fooRepo) {
        this.fooRepo = fooRepo;
}
@Configuration 
public class Config {}

以我的浅见,第一种选择看起来更好。

如果有用就告诉我!

 类似资料:
  • 当我启动石英调度程序时,它不会触发我的工作。我的工作被安排在每个小时。但是启动我的调度程序后,我的第一个工作在一个小时后被触发。我是石英新手。下面是我的石英启动代码

  • 我想用quartz scheduler使用jdbc数据存储立即执行作业~。然而,即使我使用now()或调用triggerjob进行调度,在调度和触发器fire之间也有20-30秒的延迟。 我尝试用一个简单的触发器执行作业: 并且我还尝试用调度程序触发: 下面是显示延迟的侦听器日志。

  • 乡亲们, 我正在尝试用Quartz调度器实现Spring boot,以便在java中调度作业。我的经理建议根据作业id为所有作业使用具有不同实施服务的单个作业。但我不能说服所有服务实施都使用单个作业。 请指导我使用多个服务类的单个作业或为每个服务编写每个作业。 提前感谢。。

  • 我们使用quartz调度器创建一个带有触发器名称和触发器组的触发器,它将在15分钟的间隔被触发。 我们希望在任何时间点手动触发时间表。因此,我们所做的就是获取与我们创建的计划相关联的作业的触发键细节,并尝试使用以下API触发作业。 用上面提到的API激发作业时(即尝试手动激发作业)的Quartz日志: 能不能有人请让我知道我们如何才能使时间表是触发与原来的工作相关联的触发器。

  • 问题内容: 有没有一种方法可以删除带有特定作业的预定触发器?似乎删除触发器的唯一方法是删除整个作业,然后重新注册该作业并触发。 我有一份可能有100多个触发器的作业,我真的不想删除该作业,而只需要删除1个触发器就重新注册所有触发器。 另外,是否有一种方法可以在配置触发器后立即停止调度程序执行作业? 谢谢 问题答案: 尝试 这接受触发器和组名作为参数,并且只会删除指定的触发器,而不是作业。 Quar

  • 在使用Quartz Scheduler 1.8.6版的应用程序中,当作业未完成时,我们遇到了一个触发器卡住的问题。 例如,我们有ssh调用或数据库查询的作业。如果这些作业挂起(因为ssh调用没有终止,或者select语句有一个表锁),那么我将无法再触发这些作业。触发器被卡住,直到我强制重新启动调度程序。 我已经试过了。中断(触发器)和调度程序。重新调度触发器()。我试着移除触发器并重新创建它。我已